예제 #1
0
def generate_bot_execute_orders_message(message_id):
    """

    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type message_id: long
    :param message_id: the id of this message
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.BOTEXECUTE
    m.message_id = message_id
    assert m.IsInitialized()
    return m
예제 #2
0
def generate_cnc_broadcast_orders(message_id):
    """

    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type message_id: long
    :param message_id: the id of this message
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.CNCBROADCASTORDERS
    m.message_id = message_id
    assert m.IsInitialized()
    return m
예제 #3
0
def generate_globals_request_message(message_id):
    """

    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type message_id: long
    :param message_id: the id of this message
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.GLOBALS_REQUEST
    m.message_id = message_id
    assert m.IsInitialized()
    return m
예제 #4
0
def generate_terminate_message(message_id):
    """  Produces a terminate command message ready to be serialized to a string.

    :type message_id: long
    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :param message_id: the id of this message
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.TERMINATE
    m.message_id = message_id
    assert m.IsInitialized()
    return m
예제 #5
0
def generate_bot_master_place_orders_message(message_id, data):
    """

    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type data: dict
    :type message_id: long
    :param message_id: the id of this message
    :param data: a dict that contains a command
    :return: the message to be generated
    """
    serialized = cPickle.dumps(data)
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.BOTMASTERPLACEORDER
    m.message_id = message_id
    m.Extensions[botmastermessage_pb2.bm_order].serialized_dict = serialized
    assert m.IsInitialized()
    return m
예제 #6
0
def generate_cnc_host_orders_message(message_id, orders):
    """


    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type orders: str
    :type message_id: long
    :param message_id: the id of this message
    :param orders: the serialized orders to issue
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.CNCHOSTORDERS
    m.message_id = message_id
    m.Extensions[cncmessage_pb2.cnc_host].orders = orders
    assert m.IsInitialized()
    return m
예제 #7
0
def generate_payload_request(message_id, payload_name):
    """ Produces a payload request ready to be serialized to a string.


    :type message_id: long
    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type payload_name: str
    :param message_id: the id of this message
    :param payload_name: the payload that is requested
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.PAYLOAD_REQUEST
    m.message_id = message_id
    m.Extensions[payloadmessage_pb2.payload_req].payload_name = payload_name
    assert m.IsInitialized()
    return m
예제 #8
0
def generate_announce_message(message_id, announce_type, delegate_type):
    """  Produces an announcement message ready to be serialized to a string.

    :param delegate_type: the associated delegate, used internal for type casts
    :type announce_type: hystck.net.proto.announcemessage_pb2.AnnounceStatus
    :type message_id: long
    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :param message_id: the id of this message
    :param announce_type: what this message is announcing
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.ANNOUNCE
    m.message_id = message_id
    m.Extensions[announcemessage_pb2.status_info].state = announce_type
    m.Extensions[announcemessage_pb2.status_info].instance_of = delegate_type
    assert m.IsInitialized()
    return m
예제 #9
0
def generate_bot_master_get_results_message(message_id, receiving_host, receiving_port):
    """

    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type receiving_port: int
    :type receiving_host: str
    :type message_id: long
    :param message_id: the id of this message
    :param receiving_host: the host that receives the order
    :param receiving_port: the host's port
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.BOTMASTERGETRESULT
    m.message_id = message_id
    m.Extensions[botmastermessage_pb2.bm_result].receiving_host = receiving_host
    m.Extensions[botmastermessage_pb2.bm_result].receiving_port = receiving_port
    assert m.IsInitialized()
    return m
예제 #10
0
def generate_payload_message_uri(message_id, source_type, uri):
    """ Produces a payload message redirecting to an uri payload ready to be serialized to a string.


    :type source_type: hystck.net.proto.payloadmessage_pb2.SourceType
    :type message_id: long
    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type uri: str
    :param message_id: the id of this message
    :param source_type: the type of service behind the uri
    :param uri: the uri where the payload package is located
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.PAYLOAD
    m.message_id = message_id
    m.Extensions[payloadmessage_pb2.payload_info].source_type = source_type
    m.Extensions[payloadmessage_pb2.payload_info].source = uri
    assert m.IsInitialized()
    return m
예제 #11
0
def generate_payload_message_embedded(message_id, content):
    """ Produces a payload message with embedded payload ready to be serialized to a string.



    :type message_id: long
    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type content: str
    :param message_id: the id of this message
    :param content: binary representation of a payload package
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.PAYLOAD
    m.message_id = message_id
    m.Extensions[payloadmessage_pb2.payload_info].source_type = payloadmessage_pb2.EMBEDDED
    m.Extensions[payloadmessage_pb2.payload_info].size = len(content)
    m.Extensions[payloadmessage_pb2.payload_info].content = content
    assert m.IsInitialized()
    return m
예제 #12
0
def generate_globals_answer_message(message_id, globals_dict):
    """

    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type globals_dict: dict
    :type message_id: long
    :param message_id: the id of this message
    :param globals_dict: the dict containing the globals
    :return: the message to be generated
    :raise TypeError: is thrown if globals_dict is no dict
    """
    if isinstance(globals_dict, dict):
        m = genericmessage_pb2.GenericMessage()
        m.message_type = messagetypes_pb2.GLOBALS_ANSWER
        m.message_id = message_id
        serialized_dict = cPickle.dumps(globals_dict)
        m.Extensions[genericdatamessage_pb2.data].content = serialized_dict
        assert m.IsInitialized()
        return m
    else:
        raise TypeError("globals_dict needs to be of type dict")
예제 #13
0
def generate_cnc_push_orders_message(message_id, host, port):
    """



    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type port: int
    :type host: str
    :type message_id: long
    :param message_id: the id of this message
    :param host: the host that receives the order
    :param port: the host's port
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.CNCPUSHORDERS
    m.message_id = message_id
    m.Extensions[cncmessage_pb2.cnc_push].host = host
    m.Extensions[cncmessage_pb2.cnc_push].port = port
    assert m.IsInitialized()
    return m
예제 #14
0
def generate_answer_message(message_id, is_ok, original_command, return_value):
    """

    :type return_value: str
    :param return_value: additional information about operation
    :type original_command: bytearray
    :param original_command: serialized original message
    :type is_ok: bool
    :param is_ok: was the command executed successfully
    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type message_id: long
    :param message_id: the id of this message
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.ANSWER
    m.message_id = message_id
    m.Extensions[answermessage_pb2.answer_info].ok = is_ok
    m.Extensions[answermessage_pb2.answer_info].request = original_command
    m.Extensions[answermessage_pb2.answer_info].answer = return_value
    assert m.IsInitialized()
    return m
예제 #15
0
def generate_bot_pull_orders_message(message_id, src_host=None, src_port=None):
    """



    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :type src_port: int
    :type src_host: str
    :type message_id: long
    :param message_id: the id of this message
    :param src_host: the host containing the order
    :param src_port: the host's port
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.BOTPULL
    m.message_id = message_id
    if (src_host is not None) and (src_port is not None):
        m.Extensions[botmessage_pb2.bot_pull].src_host = src_host
        m.Extensions[botmessage_pb2.bot_pull].src_port = src_port
    assert m.IsInitialized()
    return m
예제 #16
0
def generate_log_message(message_id, severity, source, context):
    """  Produces a log message ready to be serialized to a string.

    :type message_id: long
    :type context: basestring
    :type source: basestring
    :type severity: hystck.net.proto.logmessage_pb2.Severity
    :rtype : hystck.net.proto.genericmessage_pb2.GenericMessage
    :param message_id: the id of this message
    :param severity: the severity of what is to be logged
    :param source: what caused the log message to be generated
    :param context: what actually happened
    :return: the message to be generated
    """
    m = genericmessage_pb2.GenericMessage()
    m.message_type = messagetypes_pb2.LOG
    m.message_id = message_id
    m.Extensions[logmessage_pb2.log_info].type = severity
    m.Extensions[logmessage_pb2.log_info].source = source
    m.Extensions[logmessage_pb2.log_info].context = context
    assert m.IsInitialized()
    return m
예제 #17
0
    def listen_thread(self):
        """ This thread will listen to incoming commands by an agent instance and complete the request.
            Upon start it will tell the agent instance that it's ready by sending a state announcement.


        """
        if self.enabled:
            hello_msg = messagegenerator.generate_announce_message(
                self.message_id, announcemessage_pb2.ONLINE_ENABLED,
                self.delegate_class)
        else:
            hello_msg = messagegenerator.generate_announce_message(
                self.message_id, announcemessage_pb2.ONLINE_DISABLED,
                self.delegate_class)
        self.message_id += 1
        # tell agent that bot is ready
        self.client_socket.send(
            netutility.NetUtility.length_prefix_message(
                hello_msg.SerializeToString()))
        # request the globals
        globals_request_msg = messagegenerator.generate_globals_request_message(
            self.message_id)
        self.client_socket.send(
            netutility.NetUtility.length_prefix_message(
                globals_request_msg.SerializeToString()))
        self.message_id += 1
        # start processing messages
        while self.active:
            try:
                # receive and de-marshall the message
                msg = netutility.NetUtility.receive_prefixed_message(
                    self.client_socket)
                m = genericmessage_pb2.GenericMessage()
                m.ParseFromString(msg)
                self.logger.debug("got message: %s", str(m))
                # print "agent connector: got message>\n", str(m)
                f = self.id_mapper[m.message_type]  # get the mapped function
                ret_val = f(
                    m)  # call and pass the message to it's mapped handler
                if ret_val is None:  # if ret_val is not set, default to success
                    ret_val = (True, "success")
                # generate an answer
                ret_msg = messagegenerator.generate_answer_message(
                    self.message_id, ret_val[0], msg, ret_val[1])
                try:
                    # send the answer back
                    self.client_socket.send(
                        netutility.NetUtility.length_prefix_message(
                            ret_msg.SerializeToString()))
                except socket.error as e:
                    self.logger.error("Failure sending answer message: %s", e)
            except KeyError as e:
                # expect this if a unmapped message type was received
                self.logger.error("KeyError: %s", e)
                # print e
            except socket.error as e:
                # expect this if a serious problem has occurred with the socket
                self.logger.error("Socket Error: %s", e)
                # print "Socket Error: ", str(e)
                self.client_socket.close()
                break
            except RuntimeError as e:
                # expect this if the reading end or the socket itself has been closed
                self.logger.warning("Runtime Error: %s", e)
                # print e.message
                if e.message == 'unexpected connection close':
                    try:
                        self.client_socket.shutdown(socket.SHUT_RDWR)
                    except socket.error:
                        pass
                    finally:
                        self.client_socket.close()
                        self.logger.info("socket has been closed on demand")
                        # print 'socket has been closed by demand'
                        break
                else:
                    self.logger.error("RuntimeError: %s", e)
                    self.client_socket.close()
                    break
            except message.Error as e:
                # a unhandled error happened
                self.logger.error("ProtoBuf Error: %s", e)
예제 #18
0
    def processor_thread(self, delegate):
        """ This thread will listen to incoming announcements from the delegates associated agent.


        :type delegate: hystck.core.agentconnectorbase.AgentConnectorBaseDelegate
        :param delegate: the delegate to work with
        :raise RuntimeError:
        """
        while self.active:
            try:
                # receive a message
                msg = NetUtility.receive_prefixed_message(delegate.agent_socket)
                m = genericmessage_pb2.GenericMessage()
                m.ParseFromString(msg)
                self.logger.debug("[%s] got message> %s", delegate.ip_address, str(m))
                # print "[", delegate.ip_address, "] got message>\n", str(m)
                # check what type of message was received
                # todo implement a function mapper
                # check if it's a announcement and set the delegates state
                if m.message_type == messagetypes_pb2.ANNOUNCE:
                    if m.HasExtension(announcemessage_pb2.status_info):
                        if m.Extensions[announcemessage_pb2.status_info].state == announcemessage_pb2.ONLINE_ENABLED:
                            delegate.state = agentconnectorbase.BotStates.enabled
                            delegate.instance_of = m.Extensions[announcemessage_pb2.status_info].instance_of
                            self.logger.info("%s changed state to enabled", delegate.ip_address)
                            # print delegate.ip_address, ' changed state to enabled'
                        elif m.Extensions[announcemessage_pb2.status_info].state == announcemessage_pb2.ONLINE_DISABLED:
                            delegate.state = agentconnectorbase.BotStates.disabled
                            delegate.instance_of = m.Extensions[announcemessage_pb2.status_info].instance_of
                            self.logger.info("%s changed state to disabled", delegate.ip_address)
                            # print delegate.ip_address, ' changed state to disabled'
                        elif announcemessage_pb2.GRACEFUL_SHUTDOWN == \
                                m.Extensions[announcemessage_pb2.status_info].state:
                            delegate.state = agentconnectorbase.BotStates.offline
                            delegate.instance_of = m.Extensions[announcemessage_pb2.status_info].instance_of
                            self.logger.info("%s changed state to offline", delegate.ip_address)
                            # print delegate.ip_address, ' changed state to offline'
                        elif m.Extensions[announcemessage_pb2.status_info].state == announcemessage_pb2.CRASHED:
                            delegate.state = agentconnectorbase.BotStates.crashed
                            delegate.instance_of = m.Extensions[announcemessage_pb2.status_info].instance_of
                            self.logger.info("%s changed state to crashed", delegate.ip_address)
                            # print delegate.ip_address, ' changed state to crashed'
                        else:
                            raise RuntimeError('unhandled announce message type')
                    else:
                        raise RuntimeError('missing extension field')
                # check if it's a payload request and try to send the requested payload to agent
                elif m.message_type == messagetypes_pb2.PAYLOAD_REQUEST:
                    if m.HasExtension(payloadmessage_pb2.payload_req):
                        gid = self.bot_registry.items[delegate.ip_address].gid
                        p = self.payload_registry.request_payload(
                            m.Extensions[payloadmessage_pb2.payload_req].payload_name, gid)
                        if p is None:
                            self.logger.warning("%s requested unregistered payload", delegate.ip_address)
                            # print "requested unregistered payload"
                            m = messagegenerator.generate_payload_message_embedded(0, str())
                            delegate.agent_socket.send(NetUtility.length_prefix_message(m.SerializeToString()))
                        elif isinstance(p, Payload):
                            if p.is_embedded:
                                m = messagegenerator.generate_payload_message_embedded(0, p.embedded_data)
                                delegate.agent_socket.send(NetUtility.length_prefix_message(m.SerializeToString()))
                            else:
                                pass
                        else:
                            pass
                # check if it's an answer and update the last received message info
                elif m.message_type == messagetypes_pb2.ANSWER:
                    if m.HasExtension(answermessage_pb2.answer_info):
                        cmd = m.Extensions[answermessage_pb2.answer_info].request
                        state = m.Extensions[answermessage_pb2.answer_info].ok
                        info = m.Extensions[answermessage_pb2.answer_info].answer
                        delegate.last_answer.update(cmd, state, info)
                # bot requested the globals
                elif m.message_type == messagetypes_pb2.GLOBALS_REQUEST:
                    m = messagegenerator.generate_globals_answer_message(0, self.globals)
                    delegate.agent_socket.send(NetUtility.length_prefix_message(m.SerializeToString()))
                else:
                    self.logger.warning("%s: Unhandled message type", delegate.ip_address)
                    # print "Unhandled message type"
            except socket.error as e:
                # excepts most likely if the socket connection is broken
                self.logger.error("Socket Error: ", e)
                # print "Socket Error: ", str(e)
                delegate.agent_socket.close()
                break
            except RuntimeError as e:
                # excepts most likely if an agent wants to close it's connection gracefully
                self.logger.warning("%s: %s", delegate.ip_address, e)
                # print e.message
                if e.message == 'unexpected connection close':
                    try:
                        delegate.agent_socket.shutdown(socket.SHUT_RDWR)
                    except socket.error:
                        pass
                    finally:
                        delegate.agent_socket.close()
                        self.logger.info("%s: socket has been closed by demand", delegate.ip_address)
                        # print 'socket has been closed by demand'
                        delegate.state = agentconnectorbase.BotStates.offline
                        self.logger.info("%s changed state to offline", delegate.ip_address)
                        # print delegate.ip_address, ' changed state to offline'
                        break
                else:
                    self.logger.error("RuntimeError: %s", e)
                    delegate.agent_socket.close()
                    break
            # except Exception as e:
            #    # a different kind of error was raised
            #    print "Error: ", e.message
            except message.Error as e:
                self.logger.error("ProtoBuf Error: %s", e)