├── .gitignore
├── README.md
├── docs
└── images
│ ├── proxycannon-ng-visual.png
│ ├── sprocket.png
│ └── wwhf.png
├── nodes
└── aws
│ ├── add_route.bash
│ ├── configs
│ └── node_setup.bash
│ ├── del_route.bash
│ ├── main.tf
│ └── variables.tf
└── setup
├── control-server-setup.sh
├── install.sh
└── setup-load-balancing.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | *.tfstate
2 | *.tfstate.backup
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # proxycannon-ng
2 |
3 | >Thank you **Wild West Hackin' Fest** for your help and support in our community-driven hackathon! We've created a on-demand proxy tool that leverages cloud environments giving a user the ability to source (all) your traffic from an endless supply of cloud based IP address. Think of it as your own private TOR network for your redteam and pentest engagements. No more defenses throttling and blocking you!
4 |
5 | ### Initial Release
6 | Code and infrastructure has been developed, tested and proven viable. We're in the process of ironing out final changes and will have commits showing up this weekend (October 27/28).
7 |
8 | **Successes: **
9 |
10 | - VPN Server Build (scripted)
11 | - Client VPN (Full Tunnel)
12 | - Terraform Node Management (Build, Destroy, Routing)
13 | - AWS Multipath Node Routing (Load Balanced Exit Nodes)
14 |
15 | ### Getting Started
16 |
17 | AWS Management
18 | - Amazon AWS Account (Goal is to support multiple cloud providers, initial release is on AWS)
19 | - Launch (1) Ubuntu Server t1-micro instance, recommend public AMI ami-0f65671a86f061fcd
20 |
21 | Build OpenVPN Server
22 | - cd into setup
23 | - Run setup-load-balancing.sh (From this GIT repo)
24 |
25 | Build Exit Nodes
26 | - perform terraform prerequisites
27 | - cd in nodes/aws then run:
28 | ```
29 | terraform init
30 | terraform apply
31 | ```
32 |
33 | ### Project History
34 |
35 | Hackathon sponsored by [Sprocket Security](https://www.sprocketsecurity.com) and hosted at [Wild West Hackin' Fest 2018](https://www.wildwesthackinfest.com)
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | .
46 |
47 | ### Get Involved
48 | Follow [@sprocketsec](https://www.twitter.com/sprocketsec) on twitter for live updates during the hackathon.
49 |
50 | Join us in [Slack](https://join.slack.com/t/hackfest-hq/shared_invite/enQtNDY1NjA4ODExNzYzLWNjM2EwMDIxN2RmYTgyMjNlMjhjMTgyYzQ0NzZkZGM1OGViOGFmYmMxNzMwZTAzMTlhMTkxODljODc5YTcxZTE) to discuss, contribute and troubleshoot. We'd love to hear from you.
51 |
52 | ### Implementation Diagram
53 | 
54 |
55 | ### Special Thanks
56 | Special thanks to @i128 (@jarsnah12 on twitter) for developing the original proxycannon tool that is our inspirartion.
57 |
58 | ### Developers:
59 | Help a little or a lot and get your name listed here as a developer of an open-source security tool...looks good on a resume and sounds good at the bar ;-)
60 |
61 | [@jarsnah12](https://www.twitter.com/jarsnah12) - original proxycannon v1 author
62 | [@w9hax](https://www.twitter.com/w9hax) - mad openVPN skillz
63 | [@caseycammilleri](https://www.twitter.com/caseycammilleri) - Gets lost deep in iptables
64 | **your name here**
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/docs/images/proxycannon-ng-visual.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/secretsquirrel/proxycannon-ng/7d739ad5196c477794250b69e13dd7e85f414efd/docs/images/proxycannon-ng-visual.png
--------------------------------------------------------------------------------
/docs/images/sprocket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/secretsquirrel/proxycannon-ng/7d739ad5196c477794250b69e13dd7e85f414efd/docs/images/sprocket.png
--------------------------------------------------------------------------------
/docs/images/wwhf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/secretsquirrel/proxycannon-ng/7d739ad5196c477794250b69e13dd7e85f414efd/docs/images/wwhf.png
--------------------------------------------------------------------------------
/nodes/aws/add_route.bash:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | IP=$1
3 | # grab last ran route cmd
4 | ROUTECMD=$(cat .routecmd)
5 |
6 | # is there a last used route cmd
7 | if [ -z "$ROUTECMD" ];then
8 | echo "[!] first time adding a route"
9 | ROUTECMD="ip route add default proto static scope global table loadb nexthop via $IP weight 100"
10 | eval $ROUTECMD
11 | else
12 | # delete existing route
13 | echo "[-] deleting existing routes"
14 | ROUTECMDDEL=`echo $ROUTECMD | sed 's/ip route add/ip route del/'`
15 | eval $ROUTECMDDEL
16 | echo "[+] adding $IP to route table"
17 | ROUTECMD="$ROUTECMD nexthop via $IP weight 100 "
18 | eval $ROUTECMD
19 | fi
20 |
21 | # save last ran route to file
22 | echo $ROUTECMD > .routecmd
23 |
--------------------------------------------------------------------------------
/nodes/aws/configs/node_setup.bash:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | sudo sysctl -w net.ipv4.ip_forward=1
3 | sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
4 |
--------------------------------------------------------------------------------
/nodes/aws/del_route.bash:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | IP=$1
3 | # grab last ran route cmd
4 | ROUTECMD=$(cat .routecmd)
5 | echo $ROUTECMD
6 |
7 | # is there a last used route cmd
8 | if [ -z "$ROUTECMD" ];then
9 | echo "[!] cannot find last route cmd used. Will not delete $IP from routing table"
10 | exit 0
11 | else
12 | if [[ $(ip route show table loadb | grep -o $IP) ]];then
13 | # delete existing route
14 | echo "[-] deleting existing route"
15 | ROUTECMDDEL=`echo $ROUTECMD | sed 's/ip route add/ip route del/'`
16 | echo $ROUTECMDDEL
17 | eval $ROUTECMDDEL
18 |
19 | # add route statement without specific IP
20 | echo "[+] deleting $IP from routing table"
21 | ROUTECMD=`echo $ROUTECMD | sed "s/nexthop via $IP weight 100//"`
22 | echo $ROUTECMD
23 | eval $ROUTECMD
24 |
25 | # save last ran route to file (but always save as a 'add' statement)
26 | ROUTECMD=`echo $ROUTECMD | sed 's/ip route del/ip route add/'`
27 | echo $ROUTECMD > .routecmd
28 |
29 | else
30 | echo "[!] IP is not in the route table"
31 | exit 0
32 | fi
33 | fi
34 |
35 |
--------------------------------------------------------------------------------
/nodes/aws/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | shared_credentials_file = "~/.aws/credentials"
3 | region = "us-east-2"
4 | }
5 |
6 | resource "aws_instance" "exit-node" {
7 | ami = "ami-0f65671a86f061fcd"
8 | instance_type = "t2.micro"
9 | key_name = "proxycannon"
10 | vpc_security_group_ids = ["${aws_security_group.exit-node-sec-group.id}"]
11 | subnet_id = "subnet-b1a666fd"
12 |
13 |
14 | tags {
15 | Name = "exit-node"
16 | }
17 |
18 | # upload our provisioning scripts
19 | provisioner "file" {
20 | source = "${path.module}/configs/"
21 | destination = "/tmp/"
22 |
23 | connection {
24 | type = "ssh"
25 | user = "ubuntu"
26 | private_key = "${file("${var.aws_priv_key}")}"
27 | }
28 | }
29 |
30 | # execute our provisioning scripts
31 | provisioner "remote-exec" {
32 | script = "${path.module}/configs/node_setup.bash"
33 |
34 | connection {
35 | type = "ssh"
36 | user = "ubuntu"
37 | private_key = "${file("${var.aws_priv_key}")}"
38 | }
39 | }
40 |
41 | # modify our route table when we bring up an exit-node
42 | provisioner "local-exec" {
43 | command = "sudo ./add_route.bash ${aws_instance.exit-node.private_ip}"
44 | }
45 |
46 | # modify our route table when we destroy an exit-node
47 | provisioner "local-exec" {
48 | when = "destroy"
49 | command = "sudo ./del_route.bash ${aws_instance.exit-node.private_ip}"
50 | }
51 |
52 | }
53 |
54 |
55 | resource "aws_security_group" "exit-node-sec-group" {
56 | name = "exit-node-sec-group"
57 |
58 | egress {
59 | from_port = 0
60 | to_port = 0
61 | protocol = "-1"
62 | cidr_blocks = ["0.0.0.0/0"]
63 | }
64 | ingress {
65 | from_port = 0
66 | to_port = 0
67 | protocol = "-1"
68 | cidr_blocks = ["0.0.0.0/0"]
69 | }
70 | }
71 |
72 | #output "public_ip" {
73 | # value = "${aws_instance.exit-node.public_ip}"
74 | #}
75 |
76 | #output "private_ip" {
77 | # value = "${aws_instance.exit-node.private_ip}"
78 | #}
79 |
80 | #output "ssh_cmd" {
81 | # value = "\nssh -i ${var.aws_priv_key} ubuntu@${aws_instance.exit-node.public_ip}"
82 | #}
83 |
84 |
--------------------------------------------------------------------------------
/nodes/aws/variables.tf:
--------------------------------------------------------------------------------
1 | variable "aws_priv_key" {
2 | default = "~/.ssh/proxycannon.pem"
3 | }
4 |
--------------------------------------------------------------------------------
/setup/control-server-setup.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | cd /etc/openvpn/easy-rsa/
3 | source ./vars
4 | /etc/openvpn/easy-rsa/pkitool --initca
5 | /etc/openvpn/easy-rsa/pkitool --server server
6 | /usr/bin/openssl dhparam -out /etc/openvpn/easy-rsa/keys/dh2048.pem 2048
7 | openvpn --genkey --secret /etc/openvpn/easy-rsa/keys/ta.key
8 | /etc/openvpn/easy-rsa/pkitool client01
9 | /etc/openvpn/easy-rsa/pkitool node01
10 | systemctl start openvpn@node-server.service
11 | systemctl start openvpn@client-server.service
12 | sysctl -w net.ipv4.ip_forward=1
13 |
--------------------------------------------------------------------------------
/setup/install.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | # install deps
3 | apt install unzip git-core openvpn easy-rsa
4 |
5 | # install terraform
6 | wget https://releases.hashicorp.com/terraform/0.11.10/terraform_0.11.10_linux_amd64.zip
7 | unzip terraform_0.11.10_linux_amd64.zip
8 | cp terraform /usr/bin/
9 |
10 | # get proxycannon-ng
11 | git clone https://github.com/proxycannon/proxycannon-ng
12 |
13 | # create directory for our aws credentials
14 | mkdir ~/.aws
15 | touch ~/.aws/credentials
16 |
17 | echo "copy your aws ssh private key to ~/.ssh/proxycannon.pem and chmod 600"
18 |
19 | echo "place your aws api id and key in ~/.aws/credentials"
20 |
--------------------------------------------------------------------------------
/setup/setup-load-balancing.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | # enable ip forwarding
3 | echo 1 > /proc/sys/net/ipv4/ip_forward
4 |
5 | # use L4 (src ip, src dport, dest ip, dport) hashing for load balancing instead of L3 (src ip ,dst ip)
6 | echo 1 > /proc/sys/net/ipv4/fib_multipath_hash_policy
7 |
8 | # setup a second routing table
9 | echo "50 loadb" >> /etc/iproute2/rt_tables
10 |
11 | # set rule for openvpn client source network to use the second routing table
12 | ip rule add from 10.10.10.0/24 table loadb
13 |
14 | # always snat from eth0
15 | iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
16 |
17 | # setup load balanced default gws for second routing table
18 | # TODO these gw ips need to be dynamic. they are the far end of the
19 | #ip route add default proto static scope global table loadb nexthop via 172.31.41.121 weight 100 nexthop via 172.31.46.51 weight 100
20 |
--------------------------------------------------------------------------------