diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..4b248f9 --- /dev/null +++ b/.flake8 @@ -0,0 +1,5 @@ +[flake8] +ignore = E226,E302,E41,W605,C901 +max-line-length = 256 +exclude = tests/*,.venv/*, .vscode/* +max-complexity = 10 \ No newline at end of file diff --git a/.gitignore b/.gitignore index a115c38..15f23c4 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,8 @@ newrelic.ini newrelic_agent.log www/kits/** +logs/ +!logs/.gitkeep # CI reports diff --git a/README.md b/README.md index f4317e5..b248747 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,44 @@

## What is phishpond? -It's a pre-built docker environment which allows you to quickly, easily and safely spin up phishing kits for analysis. Out of the box you can browse, "mitm" web traffic, log mail calls to flat files and debug PHP code remotely. +It's a pre-built dockerised environment which allows you to quickly and easily spin up phishing kits for analysis. Out of the box you can host and browse kits, "mitm" web traffic, log mail and telegram calls to flat files, and debug PHP code. + +## Installing +You can use phishpond either as a CLI package, or use the included `docker-compose.yml` to build and manage the containers manually. + +### CLI +Clone the repository +```bash +git clone https://github.com/zerofox-oss/phishpond +``` + +Install the requirements +```bash +pip install -r requirements.txt +``` + +Install phishpond +```bash +pip install -e . +``` + +Run phishpond setup +```bash +phishpond --setup +``` + +Follow the prompts to build the required containers, volumes, networks, and set required variables. + +### Compose +Clone the repository +```bash +git clone https://github.com/zerofox-oss/phishpond +``` + +Run docker-compose +```bash +docker-compose up +``` ## How to use 1. `git clone https://github.com/zerofox-oss/phishpond.git` diff --git a/docker-compose.yml b/docker-compose.yml index 84fb17b..4136a78 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,29 +1,32 @@ version: "3.5" services: - webserver: + pp_webserver: build: - context: ./docker/web + context: ./phishpond/docker/web depends_on: - - mitmproxy - container_name: 'webserver' + - pp_mitmproxy + container_name: 'pp_webserver' hostname: 'phishpond.local' restart: 'always' + ports: + - "80:80" + - "443:443" environment: - - http_proxy=http://mitmproxy:8080 - - HTTPS_PROXY=http://mitmproxy:8080 + - http_proxy=http://pp_mitmproxy:8080 + - HTTPS_PROXY=http://pp_mitmproxy:8080 - XDEBUG_CONFIG="remote_host=localhost remote_port=9000 remote_enable=1" links: - - mitmproxy - - db + - pp_mitmproxy + - pp_db volumes: - ./www:/var/www/html - - ./configs/web/vhosts:/etc/apache2/sites-enabled/ - - ./configs/php/php.ini:/usr/local/etc/php/php.ini - - ./configs/php/patch.php:/usr/local/bin/patch.php - - ./configs/php/unpatch.php:/usr/local/bin/unpatch.php + - ./phishpond/docker/configs/web/vhosts:/etc/apache2/sites-enabled/ + - ./phishpond/docker/configs/php/php.ini:/usr/local/etc/php/php.ini + - ./phishpond/docker/configs/php/patch.php:/usr/local/bin/patch.php + - ./phishpond/docker/configs/php/unpatch.php:/usr/local/bin/unpatch.php - ./logs:/var/log/phishpond/ - - mitm-volume:/usr/local/share/ca-certificates/extra/ + - pp-mitm-volume:/usr/local/share/ca-certificates/extra/ command: > bash -c "cp /usr/local/share/ca-certificates/extra/mitmproxy-ca-cert.{pem,crt} && update-ca-certificates --verbose && @@ -34,67 +37,68 @@ services: aliases: - phishpond.local - mitmproxy: + pp_mitmproxy: build: - context: ./docker/mitmproxy - container_name: 'mitmproxy' + context: ./phishpond/docker/mitmproxy + container_name: 'pp_mitmproxy' restart: 'always' command: > bash -c "mitmweb --web-host 0.0.0.0 --set confdir=/home/mitmproxy/.mitmproxy --set relax_http_form_validation --ignore-hosts '(mozilla\.com|mozilla\.net|detectportal\.firefox\.com)' && chmod -R 777 /home/mitmproxy/logs/" ports: - "8080:8081" - tty: true volumes: - - mitm-volume:/home/mitmproxy/.mitmproxy/ - - ./configs/mitmproxy/config.yaml:/home/mitmproxy/.mitmproxy/config.yaml + - pp-mitm-volume:/home/mitmproxy/.mitmproxy/ + - ./phishpond/docker/configs/mitmproxy/config.yaml:/home/mitmproxy/.mitmproxy/config.yaml - ./logs:/home/mitmproxy/logs networks: - phishpond_network - browser: + pp_browser: build: context: https://github.com/jlesage/docker-firefox.git shm_size: '2gb' ports: - "5800:5800" - container_name: 'firefox' + container_name: 'pp_browser' volumes: - - browser-volume:/config:rw - - mitm-volume:/config/certs/ + - pp-browser-data:/config:rw + - pp-mitm-volume:/config/certs/ depends_on: - - mitmproxy + - pp_mitmproxy links: - - mitmproxy - - webserver + - pp_mitmproxy + - pp_webserver networks: - phishpond_network environment: - FF_PREF_PROXY_TYPE=network.proxy.type=1 - - FF_PREF_HTTP_PROXY=network.proxy.http=\"mitmproxy\" + - FF_PREF_HTTP_PROXY=network.proxy.http=\"pp_mitmproxy\" - FF_PREF_HTTP_PROXY_PORT=network.proxy.http_port=8080 - - FF_PREF_HTTPS_PROXY=network.proxy.ssl=\"mitmproxy\" + - FF_PREF_HTTPS_PROXY=network.proxy.ssl=\"pp_mitmproxy\" - FF_PREF_HTTPS_PROXY_PORT=network.proxy.ssl_port=8080 - FF_PREF_CAPTIVE_PORTAL=network.captive-portal-service.enabled=false - DISPLAY_WIDTH=1280 - DISPLAY_HEIGHT=768 - db: + pp_db: image: mysql:5.7 volumes: - - db_data:/var/lib/mysql + - pp-db-data:/var/lib/mysql restart: always - container_name: 'db' + container_name: 'pp_db' environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_DATABASE: phishpond_db MYSQL_USER: phishpond MYSQL_PASSWORD: password + networks: + - phishpond_network volumes: - mitm-volume: - browser-volume: - db_data: + pp-mitm-volume: + pp-browser-data: + pp-db-data: networks: phishpond_network: diff --git a/docker/mitmproxy/addons/block-telegram.py b/docker/mitmproxy/addons/block-telegram.py deleted file mode 100644 index 5c04731..0000000 --- a/docker/mitmproxy/addons/block-telegram.py +++ /dev/null @@ -1,46 +0,0 @@ -""" -Add a new mitmproxy option. -Block outgoing Telegram API messages, and log -author: @teachemtechy - -Usage: - - mitmproxy -s block-telegram.py -""" -from mitmproxy import ctx, http, log -from mitmproxy.addons import termlog -import json - -class BlockTelegram: - def __init__(self): - self.outfile = '/home/mitmproxy/logs/telegram.log' - - def load(self, loader): - loader.add_option( - name = "block_telegram", - typespec = bool, - default = True, - help = "Block and log outgoing Telegram API calls", - ) - - def response(self, flow): - telegram_api_domain = 'api.telegram.org' - if flow.request.pretty_host.endswith(telegram_api_domain): - data = {} - data['payload'] = flow.request.get_text() - data['headers'] = {key: value for (key, value) in flow.request.headers.items()} - data['url'] = flow.request.pretty_url - with open(self.outfile, 'a') as fd: - json.dump(data, fd) - fd.write('\n') - - flow.response = http.HTTPResponse.make( - 201, - b"Logged data to logs/telegram.log", - {"Content-Type": "text/html"} - ) - - -addons = [ - BlockTelegram() -] \ No newline at end of file diff --git a/docker/web/ioncube_loader_lin_7.4.so b/docker/web/ioncube_loader_lin_7.4.so deleted file mode 100644 index 15eac75..0000000 Binary files a/docker/web/ioncube_loader_lin_7.4.so and /dev/null differ diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..215d679 --- /dev/null +++ b/install.sh @@ -0,0 +1 @@ +pip3 install -e . \ No newline at end of file diff --git a/logs/mail.log b/logs/.gitkeep similarity index 100% rename from logs/mail.log rename to logs/.gitkeep diff --git a/phishpond/__init__.py b/phishpond/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/phishpond/__main__.py b/phishpond/__main__.py new file mode 100755 index 0000000..54ed3d7 --- /dev/null +++ b/phishpond/__main__.py @@ -0,0 +1,46 @@ +from rich import print +from .menus import Menus as menus +from .runner import start_stop, print_status +from .client import attach, setup, configure +import argparse + +def setup_args(): + parser = argparse.ArgumentParser() + parser.add_argument( + '--setup', + help='Perform setup or rebuild operations', + action="store_true", + required=False) + return parser + + +def main(): + p = setup_args() + args = p.parse_args() + + if args.setup: + setup() + return + + try: + print(menus.banner) + print("Feature requests and PR's welcome!\nhttps://github.com/zerofox-oss/phishpond\n") + while True: + result = menus.launcher() + + if result == "Start/Stop": + start_stop() + if result == "Attach": + attach() + if result == "Configure": + configure() + if result == "Status": + print_status() + if result == "Exit": + return + except KeyboardInterrupt: + return + + +if __name__ == "__main__": + main() diff --git a/phishpond/client.py b/phishpond/client.py new file mode 100644 index 0000000..8492c6c --- /dev/null +++ b/phishpond/client.py @@ -0,0 +1,258 @@ +import docker +import docker.errors +import os +from .menus import Menus as menus +from rich.progress import Progress, TimeElapsedColumn, BarColumn +from bullet import Bullet +import re +from rich.prompt import Confirm +from rich import print +from .configs import Configs, cfg +import time + + +docker_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "docker")) + +images = { + "pp_mitmproxy": {"path": f"{docker_path}/mitmproxy", "config": Configs.mitmproxy}, + "pp_mysql_db": {"path": f"{docker_path}/mysql_db", "config": Configs.mysql_db}, + "pp_postgres_db": { + "path": f"{docker_path}/postgres_db", + "config": Configs.postgres_db, + }, + "pp_webserver": {"path": f"{docker_path}/web", "config": Configs.webserver}, + "pp_browser": {"path": f"{docker_path}/browser", "config": Configs.browser}, +} + + +def get_status(): + states = {} + client = docker.from_env() + for image in images.keys(): + try: + c = client.containers.get(image) + if c.status == "running": + states[image] = c.status + else: + states[image] = "not_running" + except docker.errors.NotFound: + states[image] = "not_running" + return states + + +def attach(): + containers = get_status() + running = [name for name, status in containers.items() if status == "running"] + if not running: + print("No containers currently running") + return + + cli = Bullet( + prompt="Select a container\n", choices=[*running], bullet=">>", margin=2 + ) + selection = cli.launch() + + print("\n") + os.system(f"docker exec -e 'TERM=xterm-256color' -it {selection} /bin/bash") + print("\n") + + +def setup(): + client = docker.from_env() + + existing = {} + for image in images: + try: + client.images.get(image) + existing[image] = images[image] + except docker.errors.ImageNotFound: + continue + + if len(existing) > 0: + choice = Confirm.ask("\nLooks like some modules are already built. Rebuild?") + if choice is False: + # menus.delete_line(len(existing) + 2) + return + + # stop and remove images + stop_phishpond() + for image in images: + try: + client.images.remove(image, force=True) + except docker.errors.NotFound: + continue + + # make volumes + v_choice = menus.volume_prompt() + for vol in v_choice: + try: + v = client.volumes.get(vol) + v.remove() + except docker.errors.NotFound: + pass + client.volumes.create(vol) + print(f"Created docker volume: {vol}") + print("Docker volume creation complete\n") + + # make network + try: + n = client.networks.get("pp_network") + n.remove() + except docker.errors.NotFound: + pass + client.networks.create("pp_network", driver="bridge", check_duplicate=True) + print("Created docker bridge network: pp_network\n") + + # validate config + valid_config = Configs.validate_mounts() + while not valid_config: + print("\nSet required mount paths") + key = menus.config_key("MOUNTS") + if key == "Exit": + return + + value = menus.config_input("MOUNTS", key) + value = value.strip() + + if not value or cfg["MOUNTS"][key] == value: + pass + else: + cfg.set("MOUNTS", key, value) + with open(os.path.join(os.path.dirname(__file__), "config.ini"), "w") as ini: + cfg.write(ini) + valid_config = Configs.validate_mounts() + + # build images + client = docker.APIClient(base_url="unix://var/run/docker.sock") + i = 0 + for image in images: + i += 1 + with Progress( + "[progress.description]{task.description}", + BarColumn(), + "[progress.percentage]{task.percentage:>3.0f}%", + TimeElapsedColumn(), + ) as progress: + task = progress.add_task( + f"[{i}/{len(images)}] Building {image}", total=100, start=True + ) + streamer = client.build( + decode=True, path=images[image]["path"], tag=image, rm=True + ) + for chunk in streamer: + if "stream" in chunk: + for line in chunk["stream"].splitlines(): + if re.match(r"^Step \d{1,2}\/\d{1,2} :", line): + stat = ( + re.findall(r" \d{1,2}\/\d{1,2} ", line)[0] + .strip() + .split("/") + ) + progress.update(task, total=int(stat[1]), advance=1) + # print(line) + + print("Docker image creation complete") + return + + +def kill(module): + client = docker.from_env() + with Progress( + "[progress.description]{task.description}", + BarColumn(), + "[progress.percentage]{task.percentage:>3.0f}%", + TimeElapsedColumn(), + ) as progress: + task = progress.add_task(f"Stopping {module}", total=100, start=True) + try: + c = client.containers.get(module) + c.stop(timeout=10) + except docker.errors.NotFound: + pass + progress.update(task, total=1, advance=1) + + +def stop_phishpond(): + containers = get_status() + running = [name for name, status in containers.items() if status == "running"] + for module in running: + kill(module) + print("\n") + + return + + +def run(module): + client = docker.from_env() + with Progress( + "[progress.description]{task.description}", + BarColumn(), + "[progress.percentage]{task.percentage:>3.0f}%", + TimeElapsedColumn(), + ) as progress: + task = progress.add_task(f"Starting {module}", total=1, start=True) + try: + state = "not_running" + while state != "running": + client.containers.run(module, **images[module]["config"]) + time.sleep(3) # give a few seconds for it to wake up + state = client.containers.get(module) # check status + except docker.errors.APIError as e: + if e.response.status_code == 409: + pass # already running + else: + print(e) + progress.update(task, total=1, advance=1) + + +def start_phishpond(): + result = menus.module_prompt() + result = ["pp_mitmproxy", "pp_webserver"] + result + + for module in result: + run(module) + print("\n") + + print("mitmweb:\thttp://localhost:8080") + print("webserver:\thttp://localhost:80") + if "pp_browser" in result: + print("browser:\thttp://localhost:5800") + print("\n") + + +def configure(): + section = menus.config_sections() + if section == "Exit": + return + key = menus.config_key(section) + if key == "Exit": + return + value = menus.config_input(section, key) + + if not value or cfg[section][key] == value: + return + + value = value.strip() + cfg.set(section, key, value) + with open(os.path.join(os.path.dirname(__file__), "config.ini"), "w") as ini: + cfg.write(ini) + + containers = get_status() + running = [name for name, status in containers.items() if status == "running"] + + if section == "MOUNTS" and "pp_webserver" in running: + kill("pp_webserver") + run("pp_webserver") + + if section == "MYSQL" and "pp_mysql_db" in running: + kill("pp_mysql_db") + run("pp_mysql_db") + print("You will need to rebuild the pp-mysql-db volume for new credentials to take effect") + + if section == "POSTGRES" and "pp_postgres_db" in running: + kill("pp_postgres_db") + run("pp_postgres_db") + print("You will need to rebuild the pp-postgres-db volume for new credentials to take effect") + + print("\n") + return diff --git a/phishpond/config.ini b/phishpond/config.ini new file mode 100644 index 0000000..34063eb --- /dev/null +++ b/phishpond/config.ini @@ -0,0 +1,15 @@ +[MOUNTS] +www = +logs = + +[MYSQL] +mysql_root_password = rootpassword +mysql_database = phishpond_db +mysql_user = phishpond +mysql_password = password + +[POSTGRES] +postgres_database = phishpond_db +postgres_user = phishpond +postgres_password = password + diff --git a/phishpond/configs.py b/phishpond/configs.py new file mode 100644 index 0000000..8356df5 --- /dev/null +++ b/phishpond/configs.py @@ -0,0 +1,160 @@ +import os +import configparser + +cfg = configparser.ConfigParser() + + +# class to hold container configurations +class Configs: + # TODO make these private + root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + config_path = os.path.abspath( + os.path.join(os.path.dirname(__file__), "docker", "configs") + ) + cfg.read(os.path.join(os.path.dirname(__file__), "config.ini")) + + @classmethod + def validate_mounts(cls): + valid = True + mounts = list(cfg["MOUNTS"]) + for mount in mounts: + setting = cfg["MOUNTS"][mount] + if not os.path.exists(setting): + valid = False + print(f"[{mount}] - Invalid path!") + + return valid + + mitmproxy = { + "name": "pp_mitmproxy", + "network": "phishpond_network", + "detach": True, + "remove": True, + # "auto_remove": True, + "ports": {8081: 8080}, + "volumes": { + "pp-mitm-volume": { + "bind": "/home/mitmproxy/.mitmproxy/", + "mode": "rw", + }, + f"{config_path}/mitmproxy/config.yaml": { + "bind": "/home/mitmproxy/.mitmproxy/config.yaml", + "mode": "rw", + }, + }, + "command": "mitmweb --web-host 0.0.0.0 --set confdir=/home/mitmproxy/.mitmproxy --set relax_http_form_validation --ignore-hosts '(mozilla\.com|mozilla\.net|detectportal\.firefox\.com)'", + } + + webserver = { + "name": "pp_webserver", + "network": "phishpond_network", + "hostname": "phishpond.local", + "detach": True, + "remove": True, + # "auto_remove": True, + "ports": {80: 80, 443: 443}, + "links": {"pp_mitmproxy": "pp_mitmproxy"}, + "volumes": { + "pp-mitm-volume": { + "bind": "/usr/local/share/ca-certificates/extra/", + "mode": "rw", + }, + cfg["MOUNTS"]["www"]: { + "bind": "/var/www/html", + "mode": "rw" + }, + f"{config_path}/web/vhosts": { + "bind": "/etc/apache2/sites-enabled/", + "mode": "rw", + }, + f"{config_path}/php/php.ini": { + "bind": "/usr/local/etc/php/php.ini", + "mode": "rw", + }, + f"{config_path}/php/patch.php": { + "bind": "/usr/local/bin/patch.php", + "mode": "rw", + }, + f"{config_path}/php/unpatch.php": { + "bind": "/usr/local/bin/unpatch.php", + "mode": "rw", + }, + cfg["MOUNTS"]["logs"]: { + "bind": "/var/log/phishpond/", + "mode": "rw", + }, + }, + "command": [ + "bash", + "-c", + "cp /usr/local/share/ca-certificates/extra/mitmproxy-ca-cert.{pem,crt} && update-ca-certificates --verbose && chmod -R 777 /var/log/phishpond && apache2-foreground", + ], + } + + mysql_db = { + "name": "pp_mysql_db", + "network": "phishpond_network", + "detach": True, + "remove": True, + # "auto_remove": True, + "volumes": { + "pp-mysql-db-data": { + "bind": "/var/lib/mysql", + "mode": "rw", + } + }, + "environment": [ + f'MYSQL_ROOT_PASSWORD={cfg["MYSQL"]["mysql_root_password"]}', + f'MYSQL_DATABASE={cfg["MYSQL"]["mysql_database"]}', + f'MYSQL_USER={cfg["MYSQL"]["mysql_user"]}', + f'MYSQL_PASSWORD={cfg["MYSQL"]["mysql_password"]}', + ], + } + + postgres_db = { + "name": "pp_postgres_db", + "network": "phishpond_network", + "detach": True, + "remove": True, + # "auto_remove": True, + "volumes": { + "pp-postgres-db-data": { + "bind": "/var/lib/postgresql/data", + "mode": "rw", + } + }, + "environment": [ + f'POSTGRES_DB={cfg["POSTGRES"]["postgres_database"]}', + f'POSTGRES_USER={cfg["POSTGRES"]["postgres_user"]}', + f'POSTGRES_PASSWORD={cfg["POSTGRES"]["postgres_password"]}', + ], + } + + browser = { + "name": "pp_browser", + "network": "phishpond_network", + "ports": {5800: 5800}, + "detach": True, + "remove": True, + # "auto_remove": True, + "volumes": { + "pp-browser-data": { + "bind": "/config", + "mode": "rw", + }, + "pp-mitm-volume": { + "bind": "/config/certs", + "mode": "rw", + }, + }, + "environment": [ + "FF_PREF_PROXY_TYPE=network.proxy.type=1", + 'FF_PREF_HTTP_PROXY=network.proxy.http="pp_mitmproxy"', + "FF_PREF_HTTP_PROXY_PORT=network.proxy.http_port=8080", + 'FF_PREF_HTTPS_PROXY=network.proxy.ssl="pp_mitmproxy"', + "FF_PREF_HTTPS_PROXY_PORT=network.proxy.ssl_port=8080", + "FF_PREF_CAPTIVE_PORTAL=network.captive-portal-service.enabled=false", + "DISPLAY_WIDTH=1280", + "DISPLAY_HEIGHT=768", + ], + } diff --git a/docker/web/.bashrc b/phishpond/docker/browser/.bashrc similarity index 100% rename from docker/web/.bashrc rename to phishpond/docker/browser/.bashrc diff --git a/phishpond/docker/browser/Dockerfile b/phishpond/docker/browser/Dockerfile new file mode 100644 index 0000000..0548bd7 --- /dev/null +++ b/phishpond/docker/browser/Dockerfile @@ -0,0 +1,13 @@ +# Dockerfile pulled from sprintcube/docker-compose-lamp +FROM jlesage/firefox:v1.17.0 + +ENV FF_PREF_PROXY_TYPE=network.proxy.type=1 +ENV FF_PREF_HTTP_PROXY=network.proxy.http="mitmproxy" +ENV FF_PREF_HTTP_PROXY_PORT=network.proxy.http_port=8080 +ENV FF_PREF_HTTPS_PROXY=network.proxy.ssl="mitmproxy" +ENV FF_PREF_HTTPS_PROXY_PORT=network.proxy.ssl_port=8080 +ENV FF_PREF_CAPTIVE_PORTAL=network.captive-portal-service.enabled=false +ENV DISPLAY_WIDTH=1280 +ENV DISPLAY_HEIGHT=768 + +COPY .bashrc /root/.bashrc \ No newline at end of file diff --git a/phishpond/docker/configs/.bashrc b/phishpond/docker/configs/.bashrc new file mode 100644 index 0000000..afdeafb --- /dev/null +++ b/phishpond/docker/configs/.bashrc @@ -0,0 +1,117 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +case $- in + *i*) ;; + *) return;; +esac + +# don't put duplicate lines or lines starting with space in the history. +# See bash(1) for more options +HISTCONTROL=ignoreboth + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# If set, the pattern "**" used in a pathname expansion context will +# match all files and zero or more directories and subdirectories. +#shopt -s globstar + +# make less more friendly for non-text input files, see lesspipe(1) +[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color|*-256color) color_prompt=yes;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +#force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +if [ "$color_prompt" = yes ]; then + PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' +else + PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' +fi +unset color_prompt force_color_prompt + +# If this is an xterm set the title to user@host:dir +case "$TERM" in +xterm*|rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; +*) + ;; +esac + +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + #alias dir='dir --color=auto' + #alias vdir='vdir --color=auto' + + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' +fi + +# colored GCC warnings and errors +#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + +# some more ls aliases +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' + +# Add an "alert" alias for long running commands. Use like so: +# sleep 10; alert +alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi diff --git a/configs/mitmproxy/config.yaml b/phishpond/docker/configs/mitmproxy/config.yaml similarity index 100% rename from configs/mitmproxy/config.yaml rename to phishpond/docker/configs/mitmproxy/config.yaml diff --git a/configs/php/patch.php b/phishpond/docker/configs/php/patch.php similarity index 100% rename from configs/php/patch.php rename to phishpond/docker/configs/php/patch.php diff --git a/configs/php/php.ini b/phishpond/docker/configs/php/php.ini similarity index 100% rename from configs/php/php.ini rename to phishpond/docker/configs/php/php.ini diff --git a/configs/php/unpatch.php b/phishpond/docker/configs/php/unpatch.php similarity index 100% rename from configs/php/unpatch.php rename to phishpond/docker/configs/php/unpatch.php diff --git a/configs/web/vhosts/default.conf b/phishpond/docker/configs/web/vhosts/default.conf similarity index 100% rename from configs/web/vhosts/default.conf rename to phishpond/docker/configs/web/vhosts/default.conf diff --git a/phishpond/docker/mitmproxy/.bashrc b/phishpond/docker/mitmproxy/.bashrc new file mode 100644 index 0000000..afdeafb --- /dev/null +++ b/phishpond/docker/mitmproxy/.bashrc @@ -0,0 +1,117 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +case $- in + *i*) ;; + *) return;; +esac + +# don't put duplicate lines or lines starting with space in the history. +# See bash(1) for more options +HISTCONTROL=ignoreboth + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# If set, the pattern "**" used in a pathname expansion context will +# match all files and zero or more directories and subdirectories. +#shopt -s globstar + +# make less more friendly for non-text input files, see lesspipe(1) +[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color|*-256color) color_prompt=yes;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +#force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +if [ "$color_prompt" = yes ]; then + PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' +else + PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' +fi +unset color_prompt force_color_prompt + +# If this is an xterm set the title to user@host:dir +case "$TERM" in +xterm*|rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; +*) + ;; +esac + +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + #alias dir='dir --color=auto' + #alias vdir='vdir --color=auto' + + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' +fi + +# colored GCC warnings and errors +#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + +# some more ls aliases +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' + +# Add an "alert" alias for long running commands. Use like so: +# sleep 10; alert +alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi diff --git a/docker/mitmproxy/Dockerfile b/phishpond/docker/mitmproxy/Dockerfile similarity index 84% rename from docker/mitmproxy/Dockerfile rename to phishpond/docker/mitmproxy/Dockerfile index a00e271..d8c64a8 100644 --- a/docker/mitmproxy/Dockerfile +++ b/phishpond/docker/mitmproxy/Dockerfile @@ -4,3 +4,6 @@ RUN apk add bash vim RUN mkdir /home/mitmproxy/logs RUN chmod -R 777 /home/mitmproxy/.mitmproxy /home/mitmproxy/logs COPY addons /home/mitmproxy/addons/ +COPY .bashrc /root/.bashrc + +EXPOSE 8080:8081 \ No newline at end of file diff --git a/phishpond/docker/mitmproxy/addons/block-telegram.py b/phishpond/docker/mitmproxy/addons/block-telegram.py new file mode 100644 index 0000000..46fce5f --- /dev/null +++ b/phishpond/docker/mitmproxy/addons/block-telegram.py @@ -0,0 +1,44 @@ +""" +Add a new mitmproxy option. +Block outgoing Telegram API messages, and log +author: @teachemtechy + +Usage: + + mitmproxy -s block-telegram.py +""" +from mitmproxy import http +import json + + +class BlockTelegram: + def __init__(self): + self.outfile = "/home/mitmproxy/logs/telegram.log" + + def load(self, loader): + loader.add_option( + name="block_telegram", + typespec=bool, + default=True, + help="Block and log outgoing Telegram API calls", + ) + + def response(self, flow): + telegram_api_domain = "api.telegram.org" + if flow.request.pretty_host.endswith(telegram_api_domain): + data = {} + data["payload"] = flow.request.get_text() + data["headers"] = { + key: value for (key, value) in flow.request.headers.items() + } + data["url"] = flow.request.pretty_url + with open(self.outfile, "a") as fd: + json.dump(data, fd) + fd.write("\n") + + flow.response = http.HTTPResponse.make( + 201, b"Logged data to logs/telegram.log", {"Content-Type": "text/html"} + ) + + +addons = [BlockTelegram()] diff --git a/docker/mitmproxy/addons/mail-intercept.py b/phishpond/docker/mitmproxy/addons/mail-intercept.py similarity index 65% rename from docker/mitmproxy/addons/mail-intercept.py rename to phishpond/docker/mitmproxy/addons/mail-intercept.py index e8dc439..0b84ca6 100644 --- a/docker/mitmproxy/addons/mail-intercept.py +++ b/phishpond/docker/mitmproxy/addons/mail-intercept.py @@ -7,20 +7,15 @@ mitmproxy -s mail-intercept.py """ -from mitmproxy import ctx, http +from mitmproxy import http class MailIntercept: - def request(self, flow) -> None: if flow.request.pretty_url == "http://mail.capture.phishpond/": flow.response = http.HTTPResponse.make( - 200, - b"Mail data logged", - {"Content-Type": "text/html"} + 200, b"Mail data logged", {"Content-Type": "text/html"} ) -addons = [ - MailIntercept() -] +addons = [MailIntercept()] diff --git a/phishpond/docker/mysql_db/.bashrc b/phishpond/docker/mysql_db/.bashrc new file mode 100644 index 0000000..afdeafb --- /dev/null +++ b/phishpond/docker/mysql_db/.bashrc @@ -0,0 +1,117 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +case $- in + *i*) ;; + *) return;; +esac + +# don't put duplicate lines or lines starting with space in the history. +# See bash(1) for more options +HISTCONTROL=ignoreboth + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# If set, the pattern "**" used in a pathname expansion context will +# match all files and zero or more directories and subdirectories. +#shopt -s globstar + +# make less more friendly for non-text input files, see lesspipe(1) +[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color|*-256color) color_prompt=yes;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +#force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +if [ "$color_prompt" = yes ]; then + PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' +else + PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' +fi +unset color_prompt force_color_prompt + +# If this is an xterm set the title to user@host:dir +case "$TERM" in +xterm*|rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; +*) + ;; +esac + +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + #alias dir='dir --color=auto' + #alias vdir='vdir --color=auto' + + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' +fi + +# colored GCC warnings and errors +#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + +# some more ls aliases +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' + +# Add an "alert" alias for long running commands. Use like so: +# sleep 10; alert +alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi diff --git a/phishpond/docker/mysql_db/Dockerfile b/phishpond/docker/mysql_db/Dockerfile new file mode 100644 index 0000000..d45f039 --- /dev/null +++ b/phishpond/docker/mysql_db/Dockerfile @@ -0,0 +1,9 @@ +# Dockerfile pulled from sprintcube/docker-compose-lamp +FROM mysql:5.7 + +ENV MYSQL_ROOT_PASSWORD=rootpassword +ENV MYSQL_DATABASE=phishpond_db +ENV MYSQL_USER=phishpond +ENV MYSQL_PASSWORD=password + +COPY .bashrc /root/.bashrc \ No newline at end of file diff --git a/phishpond/docker/postgres_db/.bashrc b/phishpond/docker/postgres_db/.bashrc new file mode 100644 index 0000000..afdeafb --- /dev/null +++ b/phishpond/docker/postgres_db/.bashrc @@ -0,0 +1,117 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +case $- in + *i*) ;; + *) return;; +esac + +# don't put duplicate lines or lines starting with space in the history. +# See bash(1) for more options +HISTCONTROL=ignoreboth + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# If set, the pattern "**" used in a pathname expansion context will +# match all files and zero or more directories and subdirectories. +#shopt -s globstar + +# make less more friendly for non-text input files, see lesspipe(1) +[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color|*-256color) color_prompt=yes;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +#force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +if [ "$color_prompt" = yes ]; then + PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' +else + PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' +fi +unset color_prompt force_color_prompt + +# If this is an xterm set the title to user@host:dir +case "$TERM" in +xterm*|rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; +*) + ;; +esac + +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + #alias dir='dir --color=auto' + #alias vdir='vdir --color=auto' + + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' +fi + +# colored GCC warnings and errors +#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + +# some more ls aliases +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' + +# Add an "alert" alias for long running commands. Use like so: +# sleep 10; alert +alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi diff --git a/phishpond/docker/postgres_db/Dockerfile b/phishpond/docker/postgres_db/Dockerfile new file mode 100644 index 0000000..287e0a3 --- /dev/null +++ b/phishpond/docker/postgres_db/Dockerfile @@ -0,0 +1,2 @@ +FROM postgres:11 +COPY .bashrc /root/.bashrc \ No newline at end of file diff --git a/phishpond/docker/web/.bashrc b/phishpond/docker/web/.bashrc new file mode 100644 index 0000000..afdeafb --- /dev/null +++ b/phishpond/docker/web/.bashrc @@ -0,0 +1,117 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +case $- in + *i*) ;; + *) return;; +esac + +# don't put duplicate lines or lines starting with space in the history. +# See bash(1) for more options +HISTCONTROL=ignoreboth + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# If set, the pattern "**" used in a pathname expansion context will +# match all files and zero or more directories and subdirectories. +#shopt -s globstar + +# make less more friendly for non-text input files, see lesspipe(1) +[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color|*-256color) color_prompt=yes;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +#force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +if [ "$color_prompt" = yes ]; then + PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' +else + PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' +fi +unset color_prompt force_color_prompt + +# If this is an xterm set the title to user@host:dir +case "$TERM" in +xterm*|rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; +*) + ;; +esac + +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + #alias dir='dir --color=auto' + #alias vdir='vdir --color=auto' + + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' +fi + +# colored GCC warnings and errors +#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + +# some more ls aliases +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' + +# Add an "alert" alias for long running commands. Use like so: +# sleep 10; alert +alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi diff --git a/docker/web/Dockerfile b/phishpond/docker/web/Dockerfile similarity index 93% rename from docker/web/Dockerfile rename to phishpond/docker/web/Dockerfile index 17e536f..416250d 100644 --- a/docker/web/Dockerfile +++ b/phishpond/docker/web/Dockerfile @@ -2,6 +2,9 @@ FROM php:7.4.2-apache-buster ARG DEBIAN_FRONTEND=noninteractive +EXPOSE 80 +EXPOSE 443 + # Update RUN apt-get clean && \ apt-get -y update --fix-missing && \ @@ -86,3 +89,6 @@ RUN chmod +x /usr/local/bin/phpsendmail # Cleanup RUN rm -rf /usr/src/* +ENV http_proxy=http://mitmproxy:8080 +ENV HTTPS_PROXY=http://mitmproxy:8080 +ENV XDEBUG_CONFIG="remote_host=localhost remote_port=9000 remote_enable=1" \ No newline at end of file diff --git a/docker/web/phpsendmail b/phishpond/docker/web/phpsendmail similarity index 100% rename from docker/web/phpsendmail rename to phishpond/docker/web/phpsendmail diff --git a/phishpond/menus.py b/phishpond/menus.py new file mode 100644 index 0000000..3b6f53b --- /dev/null +++ b/phishpond/menus.py @@ -0,0 +1,93 @@ +from bullet import Bullet, Check, Input +import textwrap +import sys +from .configs import cfg + + +class Menus(object): + b_opts = {"bullet": ">>", "margin": 2} + c_opts = {"check": ">>", "margin": 2} + banner = textwrap.dedent( + ( + """ + ██▓███ ██░ ██ ██▓ ██████ ██░ ██ ██▓███ ▒█████ ███▄ █ ▓█████▄ + ▓██░ ██▒▓██░ ██▒▓██▒▒██ ▒ ▓██░ ██▒▓██░ ██▒▒██▒ ██▒ ██ ▀█ █ ▒██▀ ██▌ + ▓██░ ██▓▒▒██▀▀██░▒██▒░ ▓██▄ ▒██▀▀██░▓██░ ██▓▒▒██░ ██▒▓██ ▀█ ██▒░██ █▌ + ▒██▄█▓▒ ▒░▓█ ░██ ░██░ ▒ ██▒░▓█ ░██ ▒██▄█▓▒ ▒▒██ ██░▓██▒ ▐▌██▒░▓█▄ ▌ + ▒██▒ ░ ░░▓█▒░██▓░██░▒██████▒▒░▓█▒░██▓▒██▒ ░ ░░ ████▓▒░▒██░ ▓██░░▒████▓ + ▒▓▒░ ░ ░ ▒ ░░▒░▒░▓ ▒ ▒▓▒ ▒ ░ ▒ ░░▒░▒▒▓▒░ ░ ░░ ▒░▒░▒░ ░ ▒░ ▒ ▒ ▒▒▓ ▒ + ░▒ ░ ▒ ░▒░ ░ ▒ ░░ ░▒ ░ ░ ▒ ░▒░ ░░▒ ░ ░ ▒ ▒░ ░ ░░ ░ ▒░ ░ ▒ ▒ + ░░ ░ ░░ ░ ▒ ░░ ░ ░ ░ ░░ ░░░ ░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ + ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ + ░ + """ + ) + ) + + def delete_line(count): + for i in range(count): + sys.stdout.write("\x1b[1A") + sys.stdout.write("\x1b[2K") + + @classmethod + def launcher(cls): + cli = Bullet( + choices=["Start/Stop", "Status", "Attach", "Configure", "Exit"], + **cls.b_opts + ) + selection = cli.launch() + cls.delete_line(len(cli.choices)) + return selection + + @classmethod + def module_prompt(cls): + cli = Check( + prompt="Choose additional modules (mitmproxy/webserver included by default)\n", + choices=["pp_browser", "pp_mysql_db", "pp_postgres_db"], + **cls.c_opts + ) + selection = cli.launch() + cls.delete_line(len(cli.choices) + 2) + return selection + + @classmethod + def volume_prompt(cls): + vols = ["pp-mitm-volume", "pp-mysql-db-data", "pp-postgres-db-data", "pp-browser-data"] + cli = Check( + prompt="Choose volumes to rebuild or press ENTER to leave all existing data\n", + choices=vols, + **cls.c_opts + ) + selection = cli.launch() + cls.delete_line(len(cli.choices) + 2) + return selection + + @classmethod + def config_sections(cls): + # get section + cli = Bullet( + prompt="Select a section\n", choices=[*cfg.sections(), "Exit"], **cls.b_opts + ) + selection = cli.launch() + cls.delete_line(len(cfg.sections()) + 3) + return selection + + @classmethod + def config_key(cls, section): + cli = Bullet( + prompt="Select a setting to edit\n", + choices=[*list(cfg[section]), "Exit"], + **cls.b_opts + ) + selection = cli.launch() + cls.delete_line(len(list(cfg[section])) + 3) + return selection + + @classmethod + def config_input(cls, section, key): + cli = Input( + prompt="Update value or press ENTER to keep existing value\n", + default=cfg[section][key], + ) + v = cli.launch() + return v diff --git a/phishpond/runner.py b/phishpond/runner.py new file mode 100644 index 0000000..d5243cb --- /dev/null +++ b/phishpond/runner.py @@ -0,0 +1,41 @@ +from rich import print +from rich.console import Console +from rich.table import Table +from .client import get_status, start_phishpond, stop_phishpond +from .configs import Configs + + +def start_stop(): + containers = get_status() + running = [name for name, status in containers.items() if status == "running"] + if not running: + valid_config = Configs.validate_mounts() + if not valid_config: + print("Please fix config issues before running phishpond\n") + return + start_phishpond() + else: + stop_phishpond() + + return + + +def print_status(): + console = Console() + status_table = Table() + status_table.add_column("Module") + status_table.add_column("State") + status_table.add_column("URL") + states = get_status() + for state in states: + url = "N/A" + if state == "pp_mitmproxy": + url = "http://localhost:8080" + if state == "pp_webserver": + url = "http://localhost:80" + if state == "pp_browser": + url = "http://localhost:5800" + status_table.add_row(state, states[state], url) + + console.print(status_table) + print("\n") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..9874cfe --- /dev/null +++ b/requirements.txt @@ -0,0 +1,24 @@ +appdirs==1.4.4 +black==21.5b1 +bullet==2.2.0 +certifi==2020.12.5 +chardet==4.0.0 +click==8.0.1 +colorama==0.4.4 +commonmark==0.9.1 +docker==4.4.4 +flake8==3.9.2 +idna==2.10 +mccabe==0.6.1 +mypy-extensions==0.4.3 +pathspec==0.8.1 +pycodestyle==2.7.0 +pyflakes==2.3.1 +Pygments==2.9.0 +regex==2021.4.4 +requests==2.25.1 +rich==10.2.2 +six==1.15.0 +toml==0.10.2 +urllib3==1.26.3 +websocket-client==0.58.0 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..f42f1ce --- /dev/null +++ b/setup.py @@ -0,0 +1,8 @@ +from setuptools import setup + +setup( + name="phishpond", + version="0.0.1", + packages=["phishpond"], + entry_points={"console_scripts": ["phishpond = phishpond.__main__:main"]}, +)