Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 14 additions & 20 deletions Docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
FROM kalilinux/kali-linux-docker
FROM phocean/msf

RUN apt update \
&& apt install -y \
apache2 \
build-essential \
git \
metasploit-framework \
postgresql \
python-dev \
python-pip
COPY "entrypoint.sh" .

RUN git clone https://github.com/NullArray/AutoSploit.git \
&& pip install -r AutoSploit/requirements.txt
RUN apt-get update && \
apt-get install -y \
git \
python-dev \
python-pip \
apache2

COPY database.yml /root/.msf4/database.yml

WORKDIR AutoSploit

EXPOSE 80 443 4444

ENTRYPOINT ["python", "autosploit.py"]
# ENTRYPOINT ["bash"]
RUN chmod +x entrypoint.sh && \
git clone https://github.com/NullArray/AutoSploit.git && \
pip install -r AutoSploit/requirements.txt

EXPOSE 4444
CMD [ "./entrypoint.sh" ]
72 changes: 8 additions & 64 deletions Docker/README.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,19 @@
# Docker deployment instructions

## tl;dr

Using [docker-compose](https://docs.docker.com/compose/install/):
## From Dockerhub

```bash
git clone https://github.com/NullArray/AutoSploit.git
cd Autosploit/Docker
docker-compose run --rm autosploit
> docker run -it battlecl0ud/autosploit
```

Using just Docker:
*Ideally this is to be replaced by project author's dockerhub account*

```bash
git clone https://github.com/NullArray/AutoSploit.git
cd Autosploit/Docker
# If you wish to edit default postgres service details, edit database.yml. Should work out of the box
# nano database.yml
docker network create -d bridge haknet
docker run --network haknet --name msfdb -e POSTGRES_PASSWORD=s3cr3t -d postgres
docker build -t autosploit .
docker run -it --network haknet -p 80:80 -p 443:443 -p 4444:4444 autosploit
```

## Abstract

- Launching `Autosploit` as a Docker container makes it very easy to use the tool in a hosted cloud environment (AWS, Azure, ...)
- Separate `postgres` database into individual service for data persistence and potential async updating of the database
- Create a small bridge network `haknet` so the service discovery is automatic
- Launch `postgres` and `Autosploit` container, both linked by `haknet`
- Autosploit will automatically launch preconfigured `msfconsole` to the external `postgres` container through `haknet` transparent network
- Total image size of Kali + Metasploit + Autosploit : 1.75GB

## Deploy

### Step 1 - Create bridge network

This will enable the Metasploit Framework to talk to the `postgres` database using its hostname, making it abstract.

A Tor Socks Proxy can also be added to perform transparent proxy when launching exploits (not for reverse shells though, obviously).

```bash
docker network create -d bridge haknet
```

### Step 2 - Launch services

All automagically linked

#### Step 2.1 - Launch postgres

Launch a vanilla `postgres` service, linked to `haknet`

```bash
docker run --network haknet --name msfdb -e POSTGRES_PASSWORD=s3cr3t -d postgres
```

#### Step 2.2 - Launch Autosploit

Launch `Autosploit`.

This Dockerfile will copy the default database config to `~/.msf4/database.yml`. You can edit the configuration file `database.yml` to your liking before building.

Please be aware that the first build will take some time (~10mn)

Building will be faster if done on a hosted server as it benefits from the -grade bandwidth
## Build it yourself

```bash
git clone https://github.com/NullArray/AutoSploit.git
cd Autosploit/Docker
nano database.yml # Exemple configuration should work fine
docker build -t autosploit .
docker run -it --network haknet -p 80:80 -p 443:443 -p 4444:4444 autosploit
> git clone https://github.com/NullArray/AutoSploit.git
> cd Autosploit/Docker
> docker build -t autosploit .
> docker run -it autosploit
```
7 changes: 7 additions & 0 deletions Docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

/etc/init.d/postgresql start
/etc/init.d/apache2 start
cd AutoSploit/

python autosploit.py
2 changes: 1 addition & 1 deletion lib/banner.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
import random

VERSION = "3.1"
VERSION = "3.1.1"


def banner_1(line_sep="#--", space=" " * 30):
Expand Down
123 changes: 78 additions & 45 deletions lib/creation/issue_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,26 @@
raw_input = input


def check_version_number(current_version):
"""
check the version number before creating an issue
"""
version_checker = re.compile(r"version.=.\S\d.\d.(\d)?", re.I)
try:
req = requests.get("https://raw.githubusercontent.com/NullArray/AutoSploit/master/lib/banner.py")
available_version = version_checker.search(req.content).group().split("=")[-1].split('"')[1]
if available_version != current_version:
return False
return True
except Exception as e:
print e
return True


def create_identifier(data):
"""
create the exception identifier
"""
obj = hashlib.sha1()
try:
obj.update(data)
Expand Down Expand Up @@ -83,7 +102,7 @@ def find_url(params):
split_information = str(html).split("\n")
for i, line in enumerate(split_information):
if searcher.search(line) is not None:
href = split_information[i - 1]
href = split_information[i]
if href is not None:
soup = BeautifulSoup(href, "html.parser")
for item in soup.findAll("a"):
Expand All @@ -93,13 +112,17 @@ def find_url(params):


def hide_sensitive():
"""
hide sensitive information from the terminal
"""
sensitive = (
"--proxy", "-P", "--personal-agent", "-q", "--query", "-C", "--config",
"--whitelist", "--msf-path"
)
args = sys.argv
for item in sys.argv:
if item in sensitive:
# TODO:/ we need to block the IP addresses in the -C argument
try:
item_index = args.index(item) + 1
hidden = ''.join([x.replace(x, "*") for x in str(args[item_index])])
Expand All @@ -119,56 +142,66 @@ def request_issue_creation(path, arguments, error_message):
"do you want to create an anonymized issue?[y/N]: "
)
if question.lower().startswith("y"):
# gonna read a chunk of it instead of one line
chunk = 4096
with open(path) as data:
identifier = create_identifier(data.read(chunk))
# gotta seek to the beginning of the file since it's already been read `4096` into it
data.seek(0)
issue_title = "Unhandled Exception ({})".format(identifier)

issue_data = {
"title": issue_title,
"body": (
"Autosploit version: `{}`\n"
"OS information: `{}`\n"
"Running context: `{}`\n"
"Error meesage: `{}`\n"
"Error traceback:\n```\n{}\n```\n"
"Metasploit launched: `{}`\n".format(
lib.banner.VERSION,
platform.platform(),
' '.join(sys.argv),
error_message,
open(path).read(),
lib.settings.MSF_LAUNCHED,
if check_version_number(lib.banner.VERSION):
# gonna read a chunk of it instead of one line
chunk = 4096
with open(path) as data:
identifier = create_identifier(error_message)
# gotta seek to the beginning of the file since it's already been read `4096` into it
data.seek(0)
issue_title = "Unhandled Exception ({})".format(identifier)

issue_data = {
"title": issue_title,
"body": (
"Autosploit version: `{}`\n"
"OS information: `{}`\n"
"Running context: `{}`\n"
"Error mesage: `{}`\n"
"Error traceback:\n```\n{}\n```\n"
"Metasploit launched: `{}`\n".format(
lib.banner.VERSION,
platform.platform(),
' '.join(sys.argv),
error_message,
open(path).read(),
lib.settings.MSF_LAUNCHED,
)
)
)
}
}

_json_data = json.dumps(issue_data)
if sys.version_info > (3,): # python 3
_json_data = _json_data.encode("utf-8")
_json_data = json.dumps(issue_data)
if sys.version_info > (3,): # python 3
_json_data = _json_data.encode("utf-8")

if not ensure_no_issue(identifier):
req = Request(
url="https://api.github.com/repos/nullarray/autosploit/issues", data=_json_data,
headers={"Authorization": "token {}".format(get_token(lib.settings.TOKEN_PATH))}
)
urlopen(req, timeout=10).read()
lib.output.info(
"issue has been generated with the title '{}', at the following "
"URL '{}'".format(
issue_title, find_url(identifier)
if not ensure_no_issue(identifier):
req = Request(
url="https://api.github.com/repos/nullarray/autosploit/issues", data=_json_data,
headers={"Authorization": "token {}".format(get_token(lib.settings.TOKEN_PATH))}
)
)
urlopen(req, timeout=10).read()
lib.output.info(
"issue has been generated with the title '{}', at the following "
"URL '{}'".format(
issue_title, find_url(identifier)
)
)
else:
lib.output.error(
"someone has already created this issue here: {}".format(find_url(identifier))
)
try:
os.remove(path)
except:
pass
else:
sep = "-" * 35
lib.output.error(
"someone has already created this issue here: {}".format(find_url(identifier))
"it appears you are not using the current version of AutoSploit please update to the newest version "
"and try again, this can also happen when a new update has been pushed and the cached raw page has "
"not been updated yet. If you feel this is the later please create and issue on AutoSploits Github "
"page with the following info:"
)
try:
os.remove(path)
except:
pass
print("{}\n{}\n{}".format(sep, open(path).read(), sep))
else:
lib.output.info("the issue has been logged to a file in path: '{}'".format(path))
5 changes: 2 additions & 3 deletions lib/exploitation/exploiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ def start_exploit(self, sep="*" * 10):
if self.dry_run:
lib.settings.close("dry run was initiated, exploitation will not be done")

lib.settings.MSF_LAUNCHED = True

today_printable = datetime.datetime.today().strftime("%Y-%m-%d_%Hh%Mm%Ss")
current_run_path = path.join(lib.settings.RC_SCRIPTS_PATH, today_printable)
try:
Expand All @@ -105,6 +103,7 @@ def start_exploit(self, sep="*" * 10):
win_total = 0
fail_total = 0
skip_amount = 0
lib.settings.MSF_LAUNCHED = True

for host in self.hosts:
host = host.strip()
Expand All @@ -113,7 +112,7 @@ def start_exploit(self, sep="*" * 10):
honey_score = api_calls.honeyscore_hook.HoneyHook(host, self.shodan_token).make_request()
if honey_score >= self.compare_honey:
lib.output.warning(
"honeypot score ({}) is above requested, skipping target".format(honey_score)
"honeypot score ({}) is above (or equal to) requested, skipping target".format(honey_score)
)
skip = True
skip_amount += 1
Expand Down