Skip to content

Commit

Permalink
feat: add windows-specific installers for some tools
Browse files Browse the repository at this point in the history
  • Loading branch information
TobiTenno committed Jul 21, 2024
1 parent 7cd8d17 commit 62f4de0
Show file tree
Hide file tree
Showing 18 changed files with 175 additions and 29 deletions.
66 changes: 60 additions & 6 deletions fsociety/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import platform
import sys
from random import choice
from typing import Optional, Union

from rich.columns import Columns
from rich.style import Style
from rich.text import Text

import fsociety.core.utilities
Expand All @@ -20,6 +22,7 @@
format_tools,
module_name,
prompt,
run_tool,
set_readline,
)

Expand Down Expand Up @@ -112,30 +115,81 @@ def agreement():
config.set("fsociety", "agreement", "true")


subcommands = list()
for item in MENU_ITEMS:
items[module_name(item)] = item

for tool in item.__tools__:
subcommands.append(
{"parent": item.__name__, "tool": tool, "name": tool.__str__()}
)
commands = list(items.keys()) + list(BUILTIN_FUNCTIONS.keys())


def errorhandle(error: Exception, style: Optional[Union[str, Style]] = "red") -> None:
console.print(str(error), style=style)
if config.getboolean("fsociety", "development"):
console.print_exception()
input("Press [Enter/Return] to return to menu... ")
return


def doexcept(error: Exception, style: Optional[Union[str, Style]] = "red") -> None:
try:
raise error
except Exception as e:
errorhandle(e, style=style)


"""
# we know it's not a command, let's see if it's a subcommand
try:
subcmd = next((subcommand for subcommand in subcommands if subcommand["name"] == selected_command))
if subcmd:
# execute parent cli, pass subcmd.name -> cli
return subcmd["tool"].run()
# looks like we didn't find a subcommand, either
return errorhandle(Exception("Invalid Command"), style="bold yellow")
except Exception as error:
return errorhandle(error)
"""

"""old
return errorhandle(Exception("Invalid Command"), style="bold yellow")
"""


def mainloop():
agreement()
console.print(choice(BANNERS), style="red", highlight=False)
print_menu_items()
selected_command = input(prompt()).strip()

def sub_command_has(sbc):
return sbc["name"] == selected_command

if not selected_command or (selected_command not in commands):
console.print("Invalid Command", style="bold yellow")
return
try:
matches = list(filter(sub_command_has, subcommands))
subcommand = None
if len(matches) > 0:
subcommand = matches[0]
if subcommand is not None:
# execute parent cli, pass subcmd.name -> cli
return run_tool(subcommand["tool"], subcommand["name"])
doexcept(Exception("Invalid Command"), style="bold yellow")
except StopIteration:
# looks like we didn't find a subcommand, either
return errorhandle(Exception("Invalid Command"), style="bold yellow")
except Exception as error:
return errorhandle(error)
if selected_command in BUILTIN_FUNCTIONS:
func = BUILTIN_FUNCTIONS.get(selected_command)
return func()
try:
func = items[selected_command].cli
return func()
except Exception as error:
console.print(str(error))
console.print_exception()
return
return errorhandle(error)


def info():
Expand Down
2 changes: 2 additions & 0 deletions fsociety/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
elif platform.startswith("linux") or platform.startswith("freebsd"):
CURRENT_PLATFORM = distro.like()


INSTALL_DIR = os.path.join(str(Path.home()), ".fsociety")
CONFIG_FILE = os.path.join(INSTALL_DIR, "fsociety.cfg")
GITHUB_PATH = "fsociety-team/fsociety"
Expand All @@ -26,6 +27,7 @@
"os": CURRENT_PLATFORM,
"host_file": "hosts.txt",
"usernames_file": "usernames.txt",
"development": "false",
}


Expand Down
24 changes: 24 additions & 0 deletions fsociety/core/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from typing import Optional, Union

from rich.style import Style

from fsociety.console import console
from fsociety.core.config import get_config

# Config
config = get_config()


def errorhandle(error: Exception, style: Optional[Union[str, Style]] = "red") -> None:
console.print(str(error), style=style)
if config.getboolean("fsociety", "development"):
console.print_exception()
input("Press [Enter/Return] to return to menu... ")
return


def doexcept(error: Exception, style: Optional[Union[str, Style]] = "red") -> None:
try:
raise error
except Exception as e:
errorhandle(e, style=style)
37 changes: 21 additions & 16 deletions fsociety/core/menu.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
import shutil
from typing import Iterable

from rich import box
Expand All @@ -9,6 +8,7 @@

from fsociety.console import console
from fsociety.core.config import INSTALL_DIR
from fsociety.core.errors import doexcept

BACK_COMMANDS = ["back", "return"]

Expand Down Expand Up @@ -78,6 +78,24 @@ def input_wait():
input("\nPress [ENTER] to continue... ")


def run_tool(tool, selected_tool: str):
if hasattr(tool, "install") and not tool.installed():
tool.install()
try:
response = tool.run()
if response and response > 0 and response != 256:
console.print(
f"{selected_tool} returned a non-zero exit code", style="bold red"
)
if hasattr(tool, "install") and confirm("Do you want to reinstall?"):
os.chdir(INSTALL_DIR)
tool.uninstall()
tool.install()
doexcept(Exception(f"{selected_tool} completed"), style="bold green on green")
except KeyboardInterrupt:
return


def tools_cli(name, tools, links=True):
table = Table(box=box.HEAVY_HEAD)
table.add_column("Name", style="red", no_wrap=True)
Expand All @@ -98,7 +116,7 @@ def tools_cli(name, tools, links=True):
console.print(table)
console.print("back", style="command")
set_readline(list(tools_dict.keys()) + BACK_COMMANDS)
selected_tool = input(prompt(name.split(".")[-2])).strip()
selected_tool = input(prompt(name.split(".")[-1])).strip()
if selected_tool not in tools_dict:
if selected_tool in BACK_COMMANDS:
return
Expand All @@ -107,20 +125,7 @@ def tools_cli(name, tools, links=True):
console.print("Invalid Command", style="bold yellow")
return tools_cli(name, tools, links)
tool = tools_dict.get(selected_tool)
if hasattr(tool, "install") and not tool.installed():
tool.install()
try:
response = tool.run()
if response and response > 0 and response != 256:
console.print(
f"{selected_tool} returned a non-zero exit code", style="bold red"
)
if hasattr(tool, "install") and confirm("Do you want to reinstall?"):
os.chdir(INSTALL_DIR)
shutil.rmtree(tool.full_path)
tool.install()
except KeyboardInterrupt:
return
run_tool(tool, selected_tool)

return input_wait()

Expand Down
41 changes: 41 additions & 0 deletions fsociety/core/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,41 @@ def clone(self, overwrite: bool = False) -> str:
raise CloneError(f"{self.full_path} not found")
return self.full_path

def uninstallable(self) -> bool:
if self.install_options:
install = self.install_options
target_os = config.get("fsociety", "os")
command = "exit 1"
if isinstance(install, dict):
if target_os == "macos" and "brew" in install and which("brew"):
return True
elif target_os == "windows" and "winget" in install and which("winget"):
return True
elif target_os == "windows" and "scoop" in install and which("scoop"):
return True
os.system(command)
return False

def uninstall(self) -> None:
if self.install_options:
install = self.install_options
target_os = config.get("fsociety", "os")
command = "exit 1"
if isinstance(install, dict):
if target_os == "macos" and "brew" in install and which("brew"):
brew_opts = install.get("brew")
command = f"brew {brew_opts}"
elif target_os == "windows" and "winget" in install and which("winget"):
winget_opts = install.get("winget")
command = f"winget install {winget_opts}"
elif target_os == "windows" and "scoop" in install and which("scoop"):
scoop_opts = install.get("scoop")
command = f"scoop {scoop_opts}"
if command == "exit 1":
rmtree(self.full_path)
else:
os.system(command)

def install(self, no_confirm: bool = False, clone: bool = True) -> None:
if no_confirm or not confirm(
f"\nDo you want to install https://github.com/{self.path}?"
Expand Down Expand Up @@ -176,6 +211,12 @@ def install(self, no_confirm: bool = False, clone: bool = True) -> None:
elif "brew" in install and which("brew"):
brew_opts = install.get("brew")
command = f"brew {brew_opts}"
elif target_os == "windows" and "winget" in install and which("winget"):
winget_opts = install.get("winget")
command = f"winget install {winget_opts}"
elif target_os == "windows" and "scoop" in install and which("scoop"):
scoop_opts = install.get("scoop")
command = f"scoop {scoop_opts}"
elif target_os in install and target_os in self.scriptable_os:
command = str(install[target_os])
else:
Expand Down
3 changes: 3 additions & 0 deletions fsociety/core/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,6 @@ def run(self):

def cli():
tools_cli(__name__, __tools__, links=False)


__name__ = "utilities"
2 changes: 1 addition & 1 deletion fsociety/information_gathering/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from .cli import __tools__, cli

__all__ = ["cli", "__tools__"] + [str(tool) for tool in __tools__]
__all__ = ["cli", "__tools__", "__name__"] + [str(tool) for tool in __tools__]
3 changes: 3 additions & 0 deletions fsociety/information_gathering/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@

def cli():
tools_cli(__name__, __tools__)


__name__ = "information_gathering"
2 changes: 1 addition & 1 deletion fsociety/networking/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from .cli import __tools__, cli

__all__ = ["cli", "__tools__"] + [str(tool) for tool in __tools__]
__all__ = ["cli", "__tools__", "__name__"] + [str(tool) for tool in __tools__]
2 changes: 1 addition & 1 deletion fsociety/networking/bettercap.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def __init__(self):
install={
"linux": "sudo apt install golang git build-essential libpcap-dev libusb-1.0-0-dev libnetfilter-queue-dev; go get -u github.com/bettercap/bettercap",
"arch": "sudo pacman -Sy bettercap",
"brew": "install bettercap",
"brew": "bettercap",
},
description="Swiss army knife for network attacks and monitoring",
)
Expand Down
3 changes: 3 additions & 0 deletions fsociety/networking/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@

def cli():
tools_cli(__name__, __tools__)


__name__ = "networking"
4 changes: 3 additions & 1 deletion fsociety/networking/nmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ def __init__(self):
path="nmap/nmap",
install={
"arch": "sudo pacman -Sy nmap",
"brew": "install nmap",
"brew": "nmap",
"linux": "sudo apt-get install nmap",
"scoop": "nmap extras/vcredist2008",
"winget": "nmap",
},
description="the Network Mapper",
)
Expand Down
2 changes: 1 addition & 1 deletion fsociety/obfuscation/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from .cli import __tools__, cli

__all__ = ["cli", "__tools__"] + [str(tool) for tool in __tools__]
__all__ = ["cli", "__tools__", "__name__"] + [str(tool) for tool in __tools__]
3 changes: 3 additions & 0 deletions fsociety/obfuscation/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@

def cli():
tools_cli(__name__, __tools__)


__name__ = "obfuscation"
2 changes: 1 addition & 1 deletion fsociety/passwords/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from .cli import __tools__, cli

__all__ = ["cli", "__tools__"] + [str(tool) for tool in __tools__]
__all__ = ["cli", "__tools__", "__name__"] + [str(tool) for tool in __tools__]
3 changes: 3 additions & 0 deletions fsociety/passwords/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@

def cli():
tools_cli(__name__, __tools__)


__name__ = "passwords"
2 changes: 1 addition & 1 deletion fsociety/web_apps/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from .cli import __tools__, cli

__all__ = ["cli", "__tools__"] + [str(tool) for tool in __tools__]
__all__ = ["cli", "__tools__", "__name__"] + [str(tool) for tool in __tools__]
3 changes: 3 additions & 0 deletions fsociety/web_apps/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@

def cli():
tools_cli(__name__, __tools__)


__name__ = "web_apps"

0 comments on commit 62f4de0

Please sign in to comment.