mirror of
https://github.com/Cronocide/wifipumpkin3.git
synced 2025-01-22 11:18:55 +00:00
Merge branch 'feature/enable-restAPI' of https://github.com/mh4x0f/WiFi-PumpkiCLI into beta
This commit is contained in:
commit
c0fb50ad6d
@ -28,7 +28,7 @@
|
||||
- Credentials harvesting
|
||||
- Transparent Proxies
|
||||
- LLMNR, NBT-NS and MDNS poisoner ([Responder3](https://github.com/skelsec/Responder3))
|
||||
- RestFulAPI (disabled)
|
||||
- RestFulAPI (new)
|
||||
- and **more**!
|
||||
|
||||
### Donation
|
||||
|
@ -15,12 +15,11 @@ loguru>=0.4.0
|
||||
scapy==2.4.3
|
||||
isc_dhcp_leases==0.9.1
|
||||
dnspython==1.16.0
|
||||
Flask>=1.1.1
|
||||
Flask==1.1.2
|
||||
requests>=2.18.4
|
||||
beautifulsoup4>=4.9.1
|
||||
black
|
||||
coverage==5.1
|
||||
# jwt>=1.0.0
|
||||
# Flask-RESTful==0.3.7
|
||||
# Werkzeug==1.0.1
|
||||
PyJWT==2.1.0
|
||||
flask-restx>=0.5.1
|
||||
|
||||
|
@ -14,10 +14,9 @@ loguru>=0.4.0
|
||||
scapy>=2.4.4
|
||||
isc_dhcp_leases>=0.9.1
|
||||
dnspython==1.16.0
|
||||
Flask==1.1.1
|
||||
Flask==1.1.2
|
||||
requests>=2.18.4
|
||||
beautifulsoup4>=4.9.1
|
||||
asn1crypto>=1.0.0
|
||||
#jwt>=1.0.0
|
||||
#Flask-RESTful==0.3.7
|
||||
#Werkzeug==1.0.1
|
||||
PyJWT==2.1.0
|
||||
flask-restx>=0.5.1
|
||||
|
@ -19,7 +19,7 @@ import wifipumpkin3.core.utility.constants as C
|
||||
from os import getuid
|
||||
|
||||
# disable RestAPI
|
||||
# from wifipumpkin3.core.servers.rest.application import RestControllerAPI
|
||||
from wifipumpkin3.core.servers.rest.application import RestControllerAPI
|
||||
import threading
|
||||
|
||||
|
||||
@ -38,27 +38,27 @@ def parser_args_func(parse_args, config):
|
||||
info=True,
|
||||
)
|
||||
)
|
||||
# if parse_args.restmode:
|
||||
# if not (parse_args.password):
|
||||
# print(
|
||||
# display_messages(
|
||||
# "{} \n rest mode require a valid password.".format(
|
||||
# setcolor("password invalid", color="red")
|
||||
# ),
|
||||
# info=True,
|
||||
# )
|
||||
# )
|
||||
# exit(0)
|
||||
if parse_args.restmode:
|
||||
if not (parse_args.password):
|
||||
print(
|
||||
display_messages(
|
||||
"{} \n rest mode require a valid password.".format(
|
||||
setcolor("password invalid", color="red")
|
||||
),
|
||||
info=True,
|
||||
)
|
||||
)
|
||||
exit(0)
|
||||
|
||||
# set_nocolors()
|
||||
# config.set_one("ap_mode", "restapi", True)
|
||||
# config.set("rest_api_settings", "PASSWORD", parse_args.password)
|
||||
# config.set("rest_api_settings", "USERNAME", parse_args.username)
|
||||
# config.set("rest_api_settings", "port", parse_args.restport)
|
||||
# server_restapi = RestControllerAPI("wp3API", config)
|
||||
# thead = threading.Thread(target=server_restapi.run)
|
||||
# thead.setDaemon(True)
|
||||
# thead.start()
|
||||
set_nocolors()
|
||||
config.set_one("ap_mode", "restapi", True)
|
||||
config.set("rest_api_settings", "PASSWORD", parse_args.password)
|
||||
config.set("rest_api_settings", "USERNAME", parse_args.username)
|
||||
config.set("rest_api_settings", "port", parse_args.restport)
|
||||
server_restapi = RestControllerAPI("wp3API", config)
|
||||
thead = threading.Thread(target=server_restapi.run)
|
||||
thead.setDaemon(True)
|
||||
thead.start()
|
||||
|
||||
|
||||
def wp3_header():
|
||||
@ -116,31 +116,31 @@ def main():
|
||||
action="store_true",
|
||||
default=False,
|
||||
)
|
||||
# parser.add_argument(
|
||||
# "--rest",
|
||||
# dest="restmode",
|
||||
# help="Run the Wp3 RESTful API.",
|
||||
# action="store_true",
|
||||
# default=False,
|
||||
# )
|
||||
# parser.add_argument(
|
||||
# "--restport",
|
||||
# dest="restport",
|
||||
# help="Port to run the Wp3 RESTful API on. default is 1337",
|
||||
# default=1337,
|
||||
# )
|
||||
# parser.add_argument(
|
||||
# "--username",
|
||||
# dest="username",
|
||||
# help="Start the RESTful API with the specified username instead of pulling from wp3.db",
|
||||
# default="wp3admin",
|
||||
# )
|
||||
# parser.add_argument(
|
||||
# "--password",
|
||||
# dest="password",
|
||||
# help="Start the RESTful API with the specified password instead of pulling from wp3.db",
|
||||
# default=None,
|
||||
# )
|
||||
parser.add_argument(
|
||||
"--rest",
|
||||
dest="restmode",
|
||||
help="Run the Wp3 RESTful API.",
|
||||
action="store_true",
|
||||
default=False,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--restport",
|
||||
dest="restport",
|
||||
help="Port to run the Wp3 RESTful API on. default is 1337",
|
||||
default=1337,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--username",
|
||||
dest="username",
|
||||
help="Start the RESTful API with the specified username instead of pulling from wp3.db",
|
||||
default="wp3admin",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--password",
|
||||
dest="password",
|
||||
help="Start the RESTful API with the specified password instead of pulling from wp3.db",
|
||||
default=None,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--version",
|
||||
|
@ -220,24 +220,24 @@ class PumpkinShell(Qt.QObject, ConsoleUI):
|
||||
self.threads["RogueAP"].extend(self.proxy_controller.ActiveReactor)
|
||||
self.threads["RogueAP"].extend(self.mitm_controller.ActiveReactor)
|
||||
|
||||
self.wireless_controller.ActiveReactor.start()
|
||||
self.wireless_controller.ActiveReactor.signalApIsRuning.connect(
|
||||
self.signalHostApdProcessIsRunning
|
||||
)
|
||||
|
||||
# if not self.parse_args.restmode:
|
||||
# self.wireless_controller.ActiveReactor.start()
|
||||
# self.wireless_controller.ActiveReactor.signalApIsRuning.connect(
|
||||
# self.signalHostApdProcessIsRunning
|
||||
# )
|
||||
# return
|
||||
|
||||
# self.wireless_controller.ActiveReactor.start()
|
||||
# for thread in self.threads["RogueAP"]:
|
||||
# if thread is not None:
|
||||
# QtCore.QThread.sleep(1)
|
||||
# if not (isinstance(thread, list)):
|
||||
# thread.start()
|
||||
# self.wireless_controller.ActiveReactor.signalApIsRuning.connect(
|
||||
# self.signalHostApdProcessIsRunning
|
||||
# )
|
||||
|
||||
if not self.parse_args.restmode:
|
||||
self.wireless_controller.ActiveReactor.start()
|
||||
self.wireless_controller.ActiveReactor.signalApIsRuning.connect(
|
||||
self.signalHostApdProcessIsRunning
|
||||
)
|
||||
return
|
||||
|
||||
self.wireless_controller.ActiveReactor.start()
|
||||
for thread in self.threads["RogueAP"]:
|
||||
if thread is not None:
|
||||
QtCore.QThread.sleep(1)
|
||||
if not (isinstance(thread, list)):
|
||||
thread.start()
|
||||
|
||||
def signalHostApdProcessIsRunning(self, status):
|
||||
if status:
|
||||
|
@ -1,5 +1,5 @@
|
||||
from flask import Blueprint
|
||||
from flask_restful import Api
|
||||
from flask_restx import Api
|
||||
import wifipumpkin3.core.servers.rest.blueprints.restapi.accesspoint as res_ap
|
||||
import wifipumpkin3.core.servers.rest.blueprints.restapi.authenticate as res_auth
|
||||
import wifipumpkin3.core.servers.rest.blueprints.restapi.logger as res_logger
|
||||
@ -48,8 +48,6 @@ def init_app(app):
|
||||
res_ap.SettingsAPmodeResource, "/apmode", "/apmode/<string:attribute>"
|
||||
)
|
||||
|
||||
api.add_resource(res_ap.ClientsResource, "/clients")
|
||||
|
||||
api.add_resource(
|
||||
res_plugins.SettingsPluginResource, "/plugins", "/plugins/<string:attribute>"
|
||||
)
|
||||
|
@ -3,7 +3,7 @@ import wifipumpkin3.core.utility.constants as C
|
||||
from wifipumpkin3 import PumpkinShell
|
||||
from wifipumpkin3.core.common.platforms import Linux as Refactor
|
||||
from netaddr import EUI
|
||||
from flask_restful import Resource
|
||||
from flask_restx import Resource
|
||||
from flask import jsonify, request
|
||||
from wifipumpkin3.core.servers.rest.ext.auth import token_required
|
||||
from wifipumpkin3.core.servers.rest.ext.exceptions import exception
|
||||
@ -25,34 +25,6 @@ from wifipumpkin3.core.servers.rest.ext.exceptions import exception
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
class ClientsResource(Resource):
|
||||
def __init__(self):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
super(ClientsResource, self).__init__()
|
||||
|
||||
def get_mac_vendor(self, mac):
|
||||
""" discovery mac vendor by mac address """
|
||||
try:
|
||||
d_vendor = EUI(mac)
|
||||
d_vendor = d_vendor.oui.registration().org
|
||||
except:
|
||||
d_vendor = "unknown vendor"
|
||||
return d_vendor
|
||||
|
||||
@token_required
|
||||
def get(self):
|
||||
proxy_plugins = self.root.proxy_controller.getInfo()
|
||||
connected_clints = Refactor.readFileDataToJson(C.CLIENTS_CONNECTED)
|
||||
list_clients_connted = []
|
||||
for item in connected_clints:
|
||||
connected_clints[item]["VENDOR"] = self.get_mac_vendor(
|
||||
connected_clints[item]["MAC"]
|
||||
)
|
||||
list_clients_connted.append(connected_clints[item])
|
||||
return jsonify({"clients": list_clients_connted})
|
||||
|
||||
|
||||
class SettingsAPmodeResource(Resource):
|
||||
config = SettingsINI.getInstance()
|
||||
key_name = "ap_mode"
|
||||
@ -95,7 +67,7 @@ class SettingsDHCPResource(Resource):
|
||||
if attribute:
|
||||
if not attribute in self.config.get_all_childname(self.key_name):
|
||||
return exception(
|
||||
"Cannot found that attribute {} on {}!".format(key, self.key_name),
|
||||
"Cannot found that attribute {} on {}!".format(attribute, self.key_name),
|
||||
code=400,
|
||||
)
|
||||
return jsonify({attribute: self.config.get(self.key_name, attribute)})
|
||||
|
@ -1,4 +1,4 @@
|
||||
from flask_restful import Resource
|
||||
from flask_restx import Resource
|
||||
from flask import request, jsonify, make_response
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
import jwt
|
||||
@ -59,9 +59,10 @@ class LoginResource(Resource):
|
||||
+ datetime.timedelta(minutes=3000),
|
||||
},
|
||||
admin_SECRET_KEY,
|
||||
algorithm="HS256",
|
||||
)
|
||||
|
||||
return jsonify({"token": token.decode("UTF-8")})
|
||||
return jsonify({"token": token})
|
||||
|
||||
return make_response(
|
||||
"Could not verify",
|
||||
|
@ -1,6 +1,6 @@
|
||||
from flask import jsonify, request
|
||||
from wifipumpkin3 import PumpkinShell
|
||||
from flask_restful import Resource
|
||||
from flask_restx import Resource
|
||||
from io import StringIO
|
||||
import sys
|
||||
from wifipumpkin3.core.servers.rest.ext.auth import token_required
|
||||
@ -37,12 +37,10 @@ class Capturing(list):
|
||||
|
||||
|
||||
class CommandsResource(Resource):
|
||||
def __init__(self):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
super(CommandsResource, self).__init__()
|
||||
|
||||
@token_required
|
||||
def get(self, command=None):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
output = []
|
||||
with Capturing(output) as output:
|
||||
self.root.onecmd(command)
|
||||
@ -50,15 +48,13 @@ class CommandsResource(Resource):
|
||||
|
||||
|
||||
class CommandsPostResource(Resource):
|
||||
def __init__(self):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
super(CommandsPostResource, self).__init__()
|
||||
|
||||
@token_required
|
||||
def post(self, command=None):
|
||||
data = request.get_json(force=True)
|
||||
if not "commands" in data:
|
||||
return exception("Cannot found that key commands on data", code=400,)
|
||||
self.root = PumpkinShell.getInstance()
|
||||
output = []
|
||||
with Capturing(output) as output:
|
||||
self.root.onecmd(data.get("commands"))
|
||||
|
@ -1,6 +1,6 @@
|
||||
from wifipumpkin3.core.utility.collection import SettingsINI
|
||||
import wifipumpkin3.core.utility.constants as C
|
||||
from flask_restful import Resource
|
||||
from flask_restx import Resource
|
||||
from flask import jsonify, request
|
||||
import os, json
|
||||
from itertools import islice
|
||||
|
@ -1,7 +1,7 @@
|
||||
from wifipumpkin3.core.utility.collection import SettingsINI
|
||||
import wifipumpkin3.core.utility.constants as C
|
||||
from wifipumpkin3 import PumpkinShell
|
||||
from flask_restful import Resource
|
||||
from flask_restx import Resource
|
||||
from flask import jsonify, request
|
||||
from wifipumpkin3.core.servers.rest.ext.auth import token_required
|
||||
from wifipumpkin3.core.servers.rest.ext.exceptions import exception
|
||||
@ -28,12 +28,9 @@ class MitmPluginsResource(Resource):
|
||||
config = SettingsINI.getInstance()
|
||||
key_name = "mitm_modules"
|
||||
|
||||
def __init__(self):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
super(MitmPluginsResource, self).__init__()
|
||||
|
||||
@token_required
|
||||
def get(self):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
mitm_plugins = self.root.mitm_controller.getInfo(excluded=("Config"))
|
||||
for item in mitm_plugins:
|
||||
mitm_plugins[item]["Activate"] = self.config.get(
|
||||
@ -46,10 +43,6 @@ class PluginsInfoResource(Resource):
|
||||
config = SettingsINI.getInstance()
|
||||
key_name = "mitm_modules"
|
||||
|
||||
def __init__(self):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
super(PluginsInfoResource, self).__init__()
|
||||
|
||||
@token_required
|
||||
def get(self, plugin_name=None):
|
||||
if plugin_name:
|
||||
@ -60,6 +53,7 @@ class PluginsInfoResource(Resource):
|
||||
),
|
||||
code=400,
|
||||
)
|
||||
self.root = PumpkinShell.getInstance()
|
||||
proxy_plugins = self.root.mitm_controller.getInfo(excluded=("Config"))
|
||||
for item in proxy_plugins:
|
||||
proxy_plugins[item]["Activate"] = self.config.get(
|
||||
@ -77,7 +71,7 @@ class SettingsPluginResource(Resource):
|
||||
if attribute:
|
||||
if not attribute in self.config.get_all_childname(self.key_name):
|
||||
return exception(
|
||||
"Cannot found that attribute {} on {}!".format(key, self.key_name),
|
||||
"Cannot found that attribute {} on {}!".format(attribute, self.key_name),
|
||||
code=400,
|
||||
)
|
||||
return jsonify({attribute: self.config.get(self.key_name, attribute)})
|
||||
|
@ -1,7 +1,7 @@
|
||||
from wifipumpkin3.core.utility.collection import SettingsINI
|
||||
import wifipumpkin3.core.utility.constants as C
|
||||
from wifipumpkin3 import PumpkinShell
|
||||
from flask_restful import Resource
|
||||
from flask_restx import Resource
|
||||
from flask import jsonify, request
|
||||
from wifipumpkin3.core.servers.rest.ext.auth import token_required
|
||||
from wifipumpkin3.core.servers.rest.ext.exceptions import exception
|
||||
@ -28,12 +28,9 @@ class ProxysPluginsResource(Resource):
|
||||
config = SettingsINI.getInstance()
|
||||
key_name = "proxy_plugins"
|
||||
|
||||
def __init__(self):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
super(ProxysPluginsResource, self).__init__()
|
||||
|
||||
@token_required
|
||||
def get(self):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
proxy_plugins = self.root.proxy_controller.getInfo(excluded=("Config"))
|
||||
list_plugins = []
|
||||
for item in proxy_plugins:
|
||||
@ -48,10 +45,6 @@ class ProxiesInfoResource(Resource):
|
||||
config = SettingsINI.getInstance()
|
||||
key_name = "proxy_plugins"
|
||||
|
||||
def __init__(self):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
super(ProxiesInfoResource, self).__init__()
|
||||
|
||||
@token_required
|
||||
def get(self, proxy_name=None):
|
||||
if proxy_name:
|
||||
@ -62,6 +55,7 @@ class ProxiesInfoResource(Resource):
|
||||
),
|
||||
code=400,
|
||||
)
|
||||
self.root = PumpkinShell.getInstance()
|
||||
proxy_plugins = self.root.proxy_controller.getInfo(excluded=("Config"))
|
||||
for item in proxy_plugins:
|
||||
proxy_plugins[item]["Activate"] = self.config.get(
|
||||
@ -74,12 +68,9 @@ class ProxiesAllInfoResource(Resource):
|
||||
config = SettingsINI.getInstance()
|
||||
key_name = "proxy_plugins"
|
||||
|
||||
def __init__(self):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
super(ProxiesAllInfoResource, self).__init__()
|
||||
|
||||
@token_required
|
||||
def get(self):
|
||||
self.root = PumpkinShell.getInstance()
|
||||
proxy_plugins = self.root.proxy_controller.getInfo(excluded=("Config"))
|
||||
for item in proxy_plugins:
|
||||
proxy_plugins[item]["Activate"] = self.config.get(
|
||||
|
@ -36,11 +36,12 @@ def token_required(f):
|
||||
|
||||
try:
|
||||
app_secret_key = conf.get("rest_api_settings", "SECRET_KEY")
|
||||
data = jwt.decode(token, app_secret_key)
|
||||
data = jwt.decode(token, app_secret_key, algorithms=["HS256"])
|
||||
app_public_id = conf.get("rest_api_settings", "public_id")
|
||||
if app_public_id != data["public_id"]:
|
||||
return make_response(jsonify({"message": "Token is invalid!"}), 401)
|
||||
except:
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return make_response(jsonify({"message": "Token is invalid!"}), 401)
|
||||
|
||||
return f(*args, **kwargs)
|
||||
|
Loading…
Reference in New Issue
Block a user