Skip to content

Commit

Permalink
v0.5.0
Browse files Browse the repository at this point in the history
Bugs
 * fixes supervisor dangling processes (thanks @oXis)
 * doxyproxy container name cant have slashes
 * wrong port displayed on doxyproxy start message when using configured
   port

Enhancements
  * Configurable port for doxyproxy (thanks @oXis)
  * Now works without `privileged=true`
  * Added support for WSL2
  * Docker daemons that run in VMs (windows/macos): use special hostname
    for haproxy that points to the VM IP running the daemon.
    `network=host` doesn't work on those environments
  * Fewer default threads
  • Loading branch information
audibleblink committed May 11, 2021
1 parent 8eb057c commit 46f6826
Showing 1 changed file with 37 additions and 22 deletions.
59 changes: 37 additions & 22 deletions doxycannon.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
#!/usr/bin/env python3

import signal
import sys
import argparse
from pathlib import Path
import os
import sys
import platform
import re
import signal
import sys

from pathlib import Path
from threading import Thread
from queue import Queue

import docker

VERSION = '0.4.5'
VERSION = '0.5.0'
IMAGE = 'audibleblink/doxycannon'
TOR = 'audibleblink/tor'
DOXY = 'audibleblink/doxyproxy'
THREADS = 20

THREADS = 10
START_PORT = 9000
HAPORT = 1337

platform = platform.uname()[3].lower()
IS_DOCKER_VM = "microsoft" in platform or "darwin" in platform

PROXYCHAINS_CONF = './proxychains.conf'
PROXYCHAINS_TEMPLATE = """
# This file is automatically generated by doxycannon. If you need changes,
Expand Down Expand Up @@ -100,7 +105,11 @@ def write_config(filename, data, conf_type):
def write_haproxy_conf(port_range):
"""Generates HAProxy config based on # of ovpn files"""
print("[+] Writing HAProxy configuration")
conf_line = "\tserver doxy{} 127.0.0.1:{} check"
if IS_DOCKER_VM:
# https://github.com/docker/for-win/issues/6736#issuecomment-630044405
conf_line = "\tserver doxy{} host.docker.internal:{} check"
else:
conf_line = "\tserver doxy{} 127.0.0.1:{} check"
data = list(map(lambda x: conf_line.format(x, x), port_range))
write_config(HAPROXY_CONF, data, 'haproxy')

Expand Down Expand Up @@ -243,32 +252,36 @@ def up(image, conf):
start_containers(image, ovpn_file_queue, port_range)


def tor(image, count):
def tor(count):
"""Start <count> tor nodes to proxy through
Will take the given number of tor nodes and start a proxy
rotator that cycles through the tor nodes
"""
if not doxy.images.list(name=image):
build(image, path='./tor/')
if not doxy.images.list(name=TOR):
build(TOR, path='./tor/')

port_range = range(START_PORT, START_PORT + count)
name_queue = Queue(maxsize=0)
for port in port_range:
name_queue.put("tor_{}".format(port))
start_containers(image, name_queue, port_range)
start_containers(TOR, name_queue, port_range)


def rotate(image, port_range):
def rotate(port_range):
"""Creates a proxy rotator, HAProxy, based on the port range provided"""
try:
write_haproxy_conf(port_range)
if not doxy.images.list(name=image):
build(image, path='./haproxy')
build(DOXY, path='./haproxy')
print('[*] Staring single-port mode...')
print('[*] Proxy rotator listening on port 1337. Ctrl-c to quit')
print(f"[*] Proxy rotator listening on port {HAPORT}. Ctrl-c to quit")
signal.signal(signal.SIGINT, signal_handler)
doxy.containers.run(DOXY, network='host', name=DOXY, auto_remove=True)
cname = DOXY.split("/")[1]
if IS_DOCKER_VM:
ports = {f"{HAPORT}/tcp": HAPORT}
doxy.containers.run(DOXY, name=cname, auto_remove=True, ports=ports)
else:
doxy.containers.run(DOXY, name=cname, auto_remove=True, network='host')
except Exception as err:
print(err)
raise
Expand All @@ -278,7 +291,7 @@ def single(image, conf):
"""Starts an HAProxy rotator.
Builds and starts the HAProxy container in the haproxy folder
This will create a local socks5 proxy on port 1337 that will
This will create a local socks5 proxy on port $HAPORT that will
allow one to configure applications with SOCKS proxy options.
Ex: Firefox, BurpSuite, etc.
"""
Expand All @@ -288,7 +301,7 @@ def single(image, conf):

ovpn_file_count = len(list(vpn_file_queue(conf).queue))
port_range = range(START_PORT, START_PORT + ovpn_file_count)
rotate(DOXY, port_range)
rotate(port_range)


def interactive(image, conf):
Expand Down Expand Up @@ -322,6 +335,7 @@ def signal_handler(*args):
print('[*] Your proxies are still running.')
sys.exit(0)


def get_parsed():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="command")
Expand Down Expand Up @@ -424,15 +438,16 @@ def get_parsed():

return parser.parse_args()


def handle_tor(args):
if args.clean:
clean(TOR)
elif args.up:
tor(TOR, args.nodes)
tor(args.nodes)
elif args.down:
down(TOR)
elif args.single:
rotate(DOXY, range(START_PORT, START_PORT+args.nodes))
rotate(range(START_PORT, START_PORT + args.nodes))


def handle_vpn(args):
Expand Down Expand Up @@ -466,9 +481,9 @@ def main(args):


if __name__ == "__main__":
try:
try:
doxy = docker.from_env()
except Exception as err:
except Exception:
print("Unable to contact local Docker daemon. Is it running?")
sys.exit(1)
args = get_parsed()
Expand Down

0 comments on commit 46f6826

Please sign in to comment.