Compare commits
17 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
b98f159811 | |
![]() |
02d5ad0d2a | |
![]() |
7d6f22c4e6 | |
![]() |
da75a4f954 | |
![]() |
a1f467ed6e | |
![]() |
bbe1b24e30 | |
![]() |
8dd2a58ba2 | |
![]() |
7f7d215305 | |
![]() |
684e47f7d5 | |
![]() |
f984e897a0 | |
![]() |
7a574188c7 | |
![]() |
1ed2f127fd | |
![]() |
397ec9fc70 | |
![]() |
f3432d20fb | |
![]() |
27b921e44f | |
![]() |
bbafd9fdf2 | |
![]() |
60be948cc0 |
|
@ -3,7 +3,7 @@
|
|||
github: spacehuhntech
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
ko_fi: spacehuhn
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 90
|
||||
daysUntilStale: 180
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
|
|
121
README.md
121
README.md
|
@ -1,115 +1,38 @@
|
|||
# ESP8266 Deauther Version 2
|
||||
# ESP8266 Deauther
|
||||
|
||||
<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>
|
||||
</p>
|
||||
<img src='https://deauther.com/img/logo.png' alt='Deauther Logo' width='200' />
|
||||
|
||||
## Difference to Version 3
|
||||
**Scan for WiFi devices, block selected connections, create dozens of networks and confuse WiFi scanners.**
|
||||
|
||||
[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.
|
||||
## New Documentation
|
||||
|
||||
| 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 | | ✅ |
|
||||
Hi 👋
|
||||
Please visit [Deauther.com](https://deauther.com) for information about this project.
|
||||
Here are some quick links:
|
||||
|
||||
## Installation
|
||||
* [Buy](https://deauther.com/docs/buy)
|
||||
* [Download](https://deauther.com/docs/download)
|
||||
* [DIY Tutorial](https://deauther.com/docs/category/diy-tutorial)
|
||||
* [Usage](https://deauther.com/docs/category/usage)
|
||||
* [FAQ](https://deauther.com/docs/faq)
|
||||
|
||||
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).
|
||||
## Password
|
||||
|
||||
## 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 password for `pwned` is `deauther`
|
||||
|
||||
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.
|
||||
## About this Project
|
||||
|
||||
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!**
|
||||
This firmware allows you to easily perform a variety of actions to test 802.11 networks using an [ESP8266](https://www.espressif.com/en/products/socs/esp8266). It's also a great project for learning about WiFi, microcontrollers, Arduino, hacking and electronics/programming in general.
|
||||
|
||||
## WiFi Jammer
|
||||
|
||||
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.
|
||||
|
||||
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)
|
||||
|
||||
## Supported Development Boards
|
||||
|
||||
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 all kind of form factores. 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)
|
||||
The deauthentication attack is the main feature, which can be used to disconnect devices from their WiFi network.
|
||||
Although this denial-of-service attack is nothing new, a lot of devices are still vulnerable to it. Luckily this is slowly changing with more WiFi 6 enabled devices being used. But a lot of outdated WiFi devices remain in place, for example in cheap IoT hardware.
|
||||
With an ESP8266 Deauther, you can easily test this attack on your 2.4GHz WiFi network/devices and see whether it's successful or not. And if it is, you know you should upgrade your network.
|
||||
|
||||
## 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!
|
||||
Neither the ESP8266, nor its SDK was meant or built for such purposes. **Bugs can occur!**
|
||||
|
||||
Use it only against your own networks and devices!
|
||||
**Use it only against your own networks and devices!**
|
||||
Please check the legal regulations in your country before using it.
|
||||
We don't take any responsibility for what you do with this program.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
A huge thanks to:
|
||||
|
||||
- [@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)
|
||||
|
||||
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:
|
||||
|
||||
- [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)
|
||||
|
||||
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!
|
||||
|
||||
## License
|
||||
|
||||
This software is licensed under the MIT License. See the [license file](LICENSE) for details.
|
||||
We don't take any responsibility for what you do with this program.
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
// #define NODEMCU
|
||||
// #define WEMOS_D1_MINI
|
||||
// #define HACKHELD_VEGA
|
||||
// #define DISPLAY_EXAMPLE_I2C
|
||||
// #define DISPLAY_EXAMPLE_SPI
|
||||
|
||||
|
@ -56,9 +57,38 @@
|
|||
|
||||
// ========== 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
|
||||
#if defined(DISPLAY_EXAMPLE_I2C)
|
||||
#elif defined(DISPLAY_EXAMPLE_I2C)
|
||||
|
||||
// ===== DISPLAY ===== //
|
||||
#define SH1106_I2C
|
||||
|
@ -347,9 +377,9 @@
|
|||
|
||||
#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
|
||||
// #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) */
|
||||
// ============================== //
|
||||
|
@ -404,10 +434,6 @@
|
|||
#define MIN_DEAUTH_FRAMES 3
|
||||
#endif /* ifndef MIN_DEAUTH_FRAMES */
|
||||
|
||||
#ifndef DEFAULT_SSID
|
||||
#define DEFAULT_SSID "pwned"
|
||||
#endif /* ifndef DEFAULT_SSID */
|
||||
|
||||
// ===== ACCESS POINT ===== //
|
||||
#ifndef AP_SSID
|
||||
#define AP_SSID "pwned"
|
||||
|
@ -581,10 +607,10 @@
|
|||
|
||||
// ======== CONSTANTS ========== //
|
||||
// Do not change these values unless you know what you're doing!
|
||||
#define DEAUTHER_VERSION "2.6.0"
|
||||
#define DEAUTHER_VERSION "2.6.1"
|
||||
#define DEAUTHER_VERSION_MAJOR 2
|
||||
#define DEAUTHER_VERSION_MINOR 6
|
||||
#define DEAUTHER_VERSION_REVISION 0
|
||||
#define DEAUTHER_VERSION_REVISION 1
|
||||
|
||||
#define EEPROM_SIZE 4095
|
||||
#define BOOT_COUNTER_ADDR 1
|
||||
|
@ -697,6 +723,7 @@
|
|||
|
||||
*/
|
||||
|
||||
|
||||
// ========== ERROR CHECKS ========== //
|
||||
#if LED_MODE_BRIGHTNESS == 0
|
||||
#error LED_MODE_BRIGHTNESS must not be zero!
|
||||
|
|
|
@ -160,7 +160,7 @@ class Attack {
|
|||
// 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 */ 0xe8, 0x03, // Interval: 0x64, 0x00 => every 100ms - 0xe8, 0x03 => every 1s
|
||||
/* 32 - 33 */ 0x64, 0x00, // Interval: 0x64, 0x00 => every 100ms - 0xe8, 0x03 => every 1s
|
||||
/* 34 - 35 */ 0x31, 0x00, // capabilities Tnformation
|
||||
|
||||
// Tagged parameters
|
||||
|
|
|
@ -565,7 +565,7 @@ void DisplayUI::setupButtons() {
|
|||
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 packet monitor, change channel
|
||||
} else if (mode == DISPLAY_MODE::CLOCK) { // when in clock, change time
|
||||
setTime(clockHour, clockMinute - 1, clockSecond);
|
||||
}
|
||||
}
|
||||
|
@ -583,7 +583,7 @@ void DisplayUI::setupButtons() {
|
|||
scan.setChannel(wifi_channel - 1);
|
||||
}
|
||||
|
||||
else if (mode == DISPLAY_MODE::CLOCK) { // when in packet monitor, change channel
|
||||
else if (mode == DISPLAY_MODE::CLOCK) { // when in clock, change time
|
||||
setTime(clockHour, clockMinute - 10, clockSecond);
|
||||
}
|
||||
}
|
||||
|
@ -938,4 +938,4 @@ void DisplayUI::setTime(int h, int m, int s) {
|
|||
clock.setMinute(clockMinute);
|
||||
clock.setSecond(clockSecond);
|
||||
#endif // ifdef RTC_DS3231
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,9 +26,9 @@ namespace led {
|
|||
LED_MODE mode = OFF;
|
||||
|
||||
#if defined(LED_NEOPIXEL_RGB)
|
||||
Adafruit_NeoPixel strip { LED_NUM, LED_NEOPIXEL_PIN, NEO_RGB + NEO_KHZ400 };
|
||||
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_KHZ400 };
|
||||
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)
|
||||
|
@ -132,4 +132,4 @@ namespace led {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace wifi {
|
|||
}
|
||||
|
||||
void setChannel(uint8_t ch) {
|
||||
if ((ch < 1) && (ch > 14)) {
|
||||
if ((ch < 1) || (ch > 14)) {
|
||||
debuglnF("ERROR: Channel must be withing the range of 1-14");
|
||||
} else {
|
||||
ap_settings.channel = ch;
|
||||
|
|
|
@ -11,6 +11,7 @@ import sys
|
|||
boards = [
|
||||
"NODEMCU",
|
||||
"WEMOS_D1_MINI",
|
||||
"HACKHELD_VEGA",
|
||||
"MALTRONICS",
|
||||
"DISPLAY_EXAMPLE_I2C",
|
||||
"DISPLAY_EXAMPLE_SPI",
|
||||
|
@ -54,14 +55,20 @@ os.system(f"mkdir {folder}")
|
|||
|
||||
for board in boards:
|
||||
print(f"Compiling {board}...", flush=True)
|
||||
|
||||
if os.path.exists(f"{folder}/esp8266_deauther_{version}_{board}.bin"):
|
||||
print("Already compiled")
|
||||
continue
|
||||
|
||||
os.system(f"arduino-cli cache clean")
|
||||
command = f"arduino-cli compile --fqbn deauther:esp8266:generic --build-properties \"build.extra_flags=-DESP8266 -D{board}\" --output-dir {folder}"
|
||||
command = f"arduino-cli compile --fqbn deauther:esp8266:generic --build-property \"build.extra_flags=-DESP8266 -D{board}\" --output-dir {folder}"
|
||||
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
|
||||
process.wait()
|
||||
os.system(f"mv {folder}/esp8266_deauther.ino.bin {folder}/esp8266_deauther_{version}_{board}.bin")
|
||||
os.system(
|
||||
f"mv {folder}/esp8266_deauther.ino.bin {folder}/esp8266_deauther_{version}_{board}.bin")
|
||||
print(f"OK")
|
||||
|
||||
os.system(f"rm {folder}/esp8266_deauther.ino.elf")
|
||||
os.system(f"rm {folder}/esp8266_deauther.ino.map")
|
||||
|
||||
print("Finished :)")
|
||||
print("Finished :)")
|
||||
|
|
|
@ -112,7 +112,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<span id="version">Version 2.6.0</span>
|
||||
<span id="version">Version 2.6.1</span>
|
||||
<br>
|
||||
<br>
|
||||
<a href="http://deauther.maltronics.com" target="_blank">Wiki</a> | <a href="info.html">Credits</a>
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<span id="version">Version 2.6.0</span>
|
||||
<span id="version">Version 2.6.1</span>
|
||||
<br>
|
||||
<br>
|
||||
<a href="http://deauther.maltronics.com" target="_blank">Wiki</a> | <a href="info.html">Credits</a>
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<span id="version">Version 2.6.0</span>
|
||||
<span id="version">Version 2.6.1</span>
|
||||
<br>
|
||||
<br>
|
||||
<a href="http://deauther.maltronics.com" target="_blank">Wiki</a> | <a href="info.html">Credits</a>
|
||||
|
|
|
@ -28,12 +28,15 @@ function convertLineBreaks(str) {
|
|||
return "";
|
||||
}
|
||||
|
||||
function showMessage(msg, closeAfter) {
|
||||
function showMessage(msg) {
|
||||
if (msg.startsWith("ERROR")) {
|
||||
getE("status").style.backgroundColor = "#d33";
|
||||
getE("status").innerHTML = "disconnected";
|
||||
|
||||
console.error("disconnected (" + msg + ")");
|
||||
} else if (msg.startsWith("LOADING")) {
|
||||
getE("status").style.backgroundColor = "#fc0";
|
||||
getE("status").innerHTML = "loading...";
|
||||
} else {
|
||||
getE("status").style.backgroundColor = "#3c5";
|
||||
getE("status").innerHTML = "connected";
|
||||
|
@ -72,11 +75,14 @@ function getFile(adr, callback, timeout, method, onTimeout, onError) {
|
|||
request.onreadystatechange = function () {
|
||||
if (this.readyState == 4) {
|
||||
if (this.status == 200) {
|
||||
showMessage("CONNECTED");
|
||||
callback(this.responseText);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
showMessage("LOADING");
|
||||
|
||||
/* send request */
|
||||
request.send();
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<span id="version">Version 2.6.0</span>
|
||||
<span id="version">Version 2.6.1</span>
|
||||
<br>
|
||||
<br>
|
||||
<a href="http://deauther.maltronics.com" target="_blank">Wiki</a> | <a href="info.html">Credits</a>
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
<div id="settingsList"></div>
|
||||
</div>
|
||||
<footer>
|
||||
<span id="version">Version 2.6.0</span>
|
||||
<span id="version">Version 2.6.1</span>
|
||||
<br>
|
||||
<br>
|
||||
<a href="http://deauther.maltronics.com" target="_blank">Wiki</a> | <a href="info.html">Credits</a>
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<span id="version">Version 2.6.0</span>
|
||||
<span id="version">Version 2.6.1</span>
|
||||
<br>
|
||||
<br>
|
||||
<a href="http://deauther.maltronics.com" target="_blank">Wiki</a> | <a href="info.html">Credits</a>
|
||||
|
|
Loading…
Reference in New Issue