mirror of
https://github.com/dobin/SuperMega
synced 2026-06-03 01:27:11 +00:00
refactor: make nicer ui, web, log
This commit is contained in:
@@ -64,3 +64,15 @@
|
|||||||
width: 40em;
|
width: 40em;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.nav-item .btn {
|
||||||
|
margin-bottom: 5px; /* Add some space between the buttons */
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-line {
|
||||||
|
border-top: 1px solid #7e7e7e; /* Create a solid line */
|
||||||
|
width: 100%; /* Span the full width of the container */
|
||||||
|
margin: 20px 0; /* Add some vertical spacing */
|
||||||
|
}
|
||||||
|
|
||||||
@@ -25,18 +25,12 @@ class Storage():
|
|||||||
self.save_data()
|
self.save_data()
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
print("Read data")
|
|
||||||
with open("app/data.pickle", "rb") as f:
|
with open("app/data.pickle", "rb") as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
data = pickle.loads(data)
|
data = pickle.loads(data)
|
||||||
|
|
||||||
for project in data:
|
|
||||||
print(" {}".format(project.name))
|
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def save_data(self):
|
def save_data(self):
|
||||||
print("Save data")
|
|
||||||
with open("app/data.pickle", "wb") as f:
|
with open("app/data.pickle", "wb") as f:
|
||||||
f.write(pickle.dumps(self.data))
|
f.write(pickle.dumps(self.data))
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-2">
|
||||||
<ul class="nav nav-tabs flex-column" id="myTab" role="tablist">
|
<ul class="nav nav-pills flex-column" id="myTab" role="tablist">
|
||||||
{% for log_file in log_files %}
|
{% for log_file in log_files %}
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
<button
|
<button
|
||||||
class="nav-link {% if loop.last %}active{% endif %}"
|
class="nav-link btn btn-light {% if loop.last %}active{% endif %}"
|
||||||
id="project-{{log_file['id']}}-tab"
|
id="project-{{log_file['id']}}-tab"
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#project-{{log_file['id']}}"
|
data-bs-target="#project-{{log_file['id']}}"
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-9">
|
<div class="col-md-10">
|
||||||
<div class="tab-content" id="myTabContent">
|
<div class="tab-content" id="myTabContent">
|
||||||
{% for log_file in log_files %}
|
{% for log_file in log_files %}
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -7,12 +7,14 @@
|
|||||||
{% include 'navigation.html' %}
|
{% include 'navigation.html' %}
|
||||||
|
|
||||||
<div class="indent">
|
<div class="indent">
|
||||||
<h1> Project {{project_name}} </h1>
|
<h2> {{project_name}} </h2>
|
||||||
<form method="POST" enctype="multipart/form-data" action="/add_project">
|
<form method="POST" enctype="multipart/form-data" action="/add_project">
|
||||||
|
<input type="hidden" name="project_name" value="{{project_name}}">
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-4">
|
<div class="col-3">
|
||||||
<input type="text" name="project_name" class="hidden form-control" value="{{project_name}}"
|
<input type="text" name="comment" class="hidden form-control" value="{{project.comment}}"
|
||||||
placeholder="Projekt" aria-label="PROJECTNAME" aria-describedby="basic-addon1">
|
placeholder="" aria-label="PROJECTNAME" aria-describedby="basic-addon1">
|
||||||
|
|
||||||
<select class="form-select" name="shellcode" aria-label="SHELLCODE">
|
<select class="form-select" name="shellcode" aria-label="SHELLCODE">
|
||||||
{% for shellcode in shellcodes %}
|
{% for shellcode in shellcodes %}
|
||||||
@@ -33,7 +35,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="col-3">
|
||||||
|
|
||||||
<select class="form-select" name="source_style" aria-label="SOURCESTYLE">
|
<select class="form-select" name="source_style" aria-label="SOURCESTYLE">
|
||||||
{% for name, value in sourcestyles %}
|
{% for name, value in sourcestyles %}
|
||||||
@@ -52,7 +54,7 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="col-3">
|
||||||
<select class="form-select" name="alloc_style" aria-label="ALLOCSTYLE">
|
<select class="form-select" name="alloc_style" aria-label="ALLOCSTYLE">
|
||||||
{% for name, value in allocstyles %}
|
{% for name, value in allocstyles %}
|
||||||
<option value="{{name}}"
|
<option value="{{name}}"
|
||||||
@@ -78,18 +80,31 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="row">
|
<div class="col-3">
|
||||||
<div class="col-4">
|
|
||||||
<button class="btn btn-primary" type="submit" value="save">Save</button>
|
<button class="btn btn-primary" type="submit" value="save">Save</button>
|
||||||
|
|
||||||
<form method="POST" enctype="multipart/form-data" action="/start_project">
|
<form method="POST" enctype="multipart/form-data" action="/start_project">
|
||||||
<input type="hidden" name="project_name" value="{{project_name}}">
|
<input type="hidden" name="project_name" value="{{project_name}}">
|
||||||
|
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" name="try_start" type="checkbox" value="checked" id="flexCheckDefault" checked>
|
||||||
|
<label class="form-check-label" for="flexCheckDefault">
|
||||||
|
Start Infected Exe
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-primary" type="submit" value="start">Start</button>
|
<button class="btn btn-primary" type="submit" value="start">Start</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="custom-line"></div> <!-- Here's the horizontal line -->
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-primary" type="submit" value="save">Save</button>
|
<button class="btn btn-primary" type="submit" value="save">Save</button>
|
||||||
<button class="btn btn-primary" type="submit" value="Verify">Verify</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
+10
-46
@@ -2,15 +2,12 @@ from flask import Blueprint, current_app, flash, request, redirect, url_for, ren
|
|||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
import io
|
|
||||||
from typing import List, Tuple
|
from typing import List, Tuple
|
||||||
from datetime import date
|
|
||||||
from pygments import highlight
|
from pygments import highlight
|
||||||
from pygments.lexers import CLexer, NasmLexer, DiffLexer, HexdumpLexer
|
from pygments.lexers import CLexer, NasmLexer, DiffLexer, HexdumpLexer
|
||||||
from pygments.formatters import HtmlFormatter
|
from pygments.formatters import HtmlFormatter
|
||||||
import difflib
|
import difflib
|
||||||
from ansi2html import Ansi2HTMLConverter
|
from ansi2html import Ansi2HTMLConverter
|
||||||
import pickle
|
|
||||||
|
|
||||||
from config import config
|
from config import config
|
||||||
from model.settings import Settings
|
from model.settings import Settings
|
||||||
@@ -66,7 +63,7 @@ def project(name):
|
|||||||
|
|
||||||
|
|
||||||
@views.route("/add_project", methods=['POST', 'GET'])
|
@views.route("/add_project", methods=['POST', 'GET'])
|
||||||
def inject():
|
def add_project():
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
|
|
||||||
@@ -135,47 +132,18 @@ def inject():
|
|||||||
@views.route("/start_project", methods=['POST', 'GET'])
|
@views.route("/start_project", methods=['POST', 'GET'])
|
||||||
def start_project():
|
def start_project():
|
||||||
#project_name = request.args.get('project_name')
|
#project_name = request.args.get('project_name')
|
||||||
project_name = request.form['project_name']
|
project_name = request.form.get('project_name')
|
||||||
|
try_start = request.form.get('try_start')
|
||||||
|
if try_start != None:
|
||||||
|
try_start = True
|
||||||
|
else:
|
||||||
|
try_start = False
|
||||||
project = storage.get_project(project_name)
|
project = storage.get_project(project_name)
|
||||||
|
project.settings.try_start_final_infected_exe = try_start
|
||||||
start(project.settings)
|
start(project.settings)
|
||||||
return redirect("/project/{}".format(project_name), code=302)
|
return redirect("/project/{}".format(project_name), code=302)
|
||||||
|
|
||||||
|
|
||||||
@views.route("/build")
|
|
||||||
def build():
|
|
||||||
exes = []
|
|
||||||
for file in os.listdir("app/upload/exe"):
|
|
||||||
exes.append(file)
|
|
||||||
|
|
||||||
shellcodes = []
|
|
||||||
for file in os.listdir("app/upload/shellcode"):
|
|
||||||
shellcodes.append(file)
|
|
||||||
|
|
||||||
sourcestyles = [(color.name, color.value) for color in SourceStyle]
|
|
||||||
allocstyles = [(color.name, color.value) for color in AllocStyle]
|
|
||||||
decoderstyles = [(color.name, color.value) for color in DecoderStyle]
|
|
||||||
execstyles = [(color.name, color.value) for color in ExecStyle]
|
|
||||||
injectstyles = [(color.name, color.value) for color in InjectStyle]
|
|
||||||
|
|
||||||
return render_template('build.html',
|
|
||||||
exes=exes,
|
|
||||||
shellcodes=shellcodes,
|
|
||||||
sourcestyles=sourcestyles,
|
|
||||||
allocstyles=allocstyles,
|
|
||||||
decoderstyles=decoderstyles,
|
|
||||||
execstyles=execstyles,
|
|
||||||
injectstyles=injectstyles,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@views.route("/files")
|
|
||||||
def files():
|
|
||||||
log_files = get_logfiles()
|
|
||||||
return render_template('files.html',
|
|
||||||
log_files=log_files
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_logfiles():
|
def get_logfiles():
|
||||||
log_files = []
|
log_files = []
|
||||||
id = 0
|
id = 0
|
||||||
@@ -184,13 +152,11 @@ def get_logfiles():
|
|||||||
for file in os.listdir(f"{logs_dir}/"):
|
for file in os.listdir(f"{logs_dir}/"):
|
||||||
if file.startswith("."):
|
if file.startswith("."):
|
||||||
continue
|
continue
|
||||||
print("Handle: ", file)
|
|
||||||
|
|
||||||
with open(os.path.join(f"{logs_dir}/", file), "r") as f:
|
with open(os.path.join(f"{logs_dir}/", file), "r") as f:
|
||||||
if file.endswith(".bin"):
|
if file.endswith(".bin"):
|
||||||
continue
|
continue
|
||||||
data = f.read()
|
data = f.read()
|
||||||
print("FILE: {}".format(file))
|
|
||||||
if 'main_c' in file:
|
if 'main_c' in file:
|
||||||
data = highlight(data, CLexer(), HtmlFormatter(full=False))
|
data = highlight(data, CLexer(), HtmlFormatter(full=False))
|
||||||
elif '_asm_' in file:
|
elif '_asm_' in file:
|
||||||
@@ -203,11 +169,9 @@ def get_logfiles():
|
|||||||
elif '.ascii' in file:
|
elif '.ascii' in file:
|
||||||
data = conv.convert(data, full=False)
|
data = conv.convert(data, full=False)
|
||||||
elif '.txt' in file:
|
elif '.txt' in file:
|
||||||
# skip it
|
continue # skip it
|
||||||
continue
|
|
||||||
elif '.hex' in file:
|
elif '.hex' in file:
|
||||||
print("-> hex")
|
continue # skip it
|
||||||
continue
|
|
||||||
#data = escape(data)
|
#data = escape(data)
|
||||||
#data = highlight(data, HexdumpLexer(), HtmlFormatter(full=False))
|
#data = highlight(data, HexdumpLexer(), HtmlFormatter(full=False))
|
||||||
elif '.log' in file:
|
elif '.log' in file:
|
||||||
|
|||||||
@@ -66,3 +66,6 @@ def setup_logging():
|
|||||||
|
|
||||||
root_logger.addHandler(ch)
|
root_logger.addHandler(ch)
|
||||||
root_logger.addHandler(list_handler)
|
root_logger.addHandler(list_handler)
|
||||||
|
|
||||||
|
def clear_log():
|
||||||
|
log_messages.clear()
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ logger = logging.getLogger("Project")
|
|||||||
class Project():
|
class Project():
|
||||||
def __init__(self, settings: Settings):
|
def __init__(self, settings: Settings):
|
||||||
self.name: str = ""
|
self.name: str = ""
|
||||||
|
self.comment: str = ""
|
||||||
self.settings: Settings = settings
|
self.settings: Settings = settings
|
||||||
self.payload: Payload = Payload(self.settings.payload_path)
|
self.payload: Payload = Payload(self.settings.payload_path)
|
||||||
self.exe_host: ExeHost = ExeHost(self.settings.inject_exe_in)
|
self.exe_host: ExeHost = ExeHost(self.settings.inject_exe_in)
|
||||||
|
|||||||
+1
-3
@@ -216,8 +216,6 @@ Trailing {sect_name} bytes:
|
|||||||
for ins in trampoline.split(';'):
|
for ins in trampoline.split(';'):
|
||||||
logger.info(f'\t{ins.strip()}')
|
logger.info(f'\t{ins.strip()}')
|
||||||
|
|
||||||
logger.info('')
|
|
||||||
|
|
||||||
return (trampoline, addrOffset)
|
return (trampoline, addrOffset)
|
||||||
|
|
||||||
|
|
||||||
@@ -245,7 +243,7 @@ Trailing {sect_name} bytes:
|
|||||||
self.compiledTrampoline = encoding
|
self.compiledTrampoline = encoding
|
||||||
self.compiledTrampolineCount = count
|
self.compiledTrampolineCount = count
|
||||||
|
|
||||||
logger.info('Successfully backdoored entry point with jump/call to shellcode')
|
logger.debug('Successfully backdoored entry point with jump/call to shellcode')
|
||||||
return instr.address
|
return instr.address
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -178,8 +178,6 @@ class SuperPe():
|
|||||||
if self.arch == 'x64':
|
if self.arch == 'x64':
|
||||||
imageBaseRelocType = SuperPe.IMAGE_REL_BASED_DIR64
|
imageBaseRelocType = SuperPe.IMAGE_REL_BASED_DIR64
|
||||||
|
|
||||||
logger.info('Adding new relocations to backdoored PE file...')
|
|
||||||
|
|
||||||
relocsSize = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].Size
|
relocsSize = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].Size
|
||||||
relocsIndex = self.getSectionIndexByDataDir(SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC)
|
relocsIndex = self.getSectionIndexByDataDir(SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC)
|
||||||
addr = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress
|
addr = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress
|
||||||
|
|||||||
@@ -3,11 +3,13 @@
|
|||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
|
import logging
|
||||||
|
|
||||||
from app.views import views
|
from app.views import views
|
||||||
from log import setup_logging, writelog
|
from log import setup_logging, writelog
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
logging.getLogger('werkzeug').setLevel(logging.ERROR)
|
||||||
setup_logging()
|
setup_logging()
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--listenip', type=str, help='IP to listen on', default="0.0.0.0")
|
parser.add_argument('--listenip', type=str, help='IP to listen on', default="0.0.0.0")
|
||||||
|
|||||||
Reference in New Issue
Block a user