Beispiel #1
0
    def generate_stager_hop(self, server, key, profile, encrypt=True, encode=True):
        """
        Generate the Python stager for hop.php redirectors that
        will perform key negotiation with the server and kick off the agent.
        """

        # read in the stager base
        f = open(self.installPath + "./data/agent/stager_hop.py")
        stager = f.read()
        f.close()

        stager = helpers.strip_python_comments(stager)

        # first line of randomized text to change up the ending RC4 string
        randomHeader = "%s='%s'\n" % (helpers.random_string(), helpers.random_string())
        stager = randomHeader + stager

        # patch the server and key information
        stager = stager.replace("REPLACE_SERVER", server)
        stager = stager.replace("REPLACE_STAGING_KEY", key)
        stager = stager.replace("REPLACE_PROFILE", profile)
        stager = stager.replace("index.jsp", self.stage1)
        stager = stager.replace("index.php", self.stage2)

        # # base64 encode the stager and return it
        # if encode:
        #     return ""
        if encrypt:
            # return an encrypted version of the stager ("normal" staging)
            # return encryption.xor_encrypt(stager, key)
            return encryption.rc4(key, stager)
        else:
            # otherwise return the case-randomized stager
            return stager
Beispiel #2
0
def build_routing_packet(stagingKey,
                         sessionID,
                         language,
                         meta="NONE",
                         additional="NONE",
                         encData=''):
    """
    Takes the specified parameters for an RC4 "routing packet" and builds/returns
    an HMAC'ed RC4 "routing packet".

    packet format:

        Routing Packet:
        +---------+-------------------+--------------------------+
        | RC4 IV  | RC4s(RoutingData) | AESc(client packet data) | ... 
        +---------+-------------------+--------------------------+
        |    4    |         16        |        RC4 length        |
        +---------+-------------------+--------------------------+
        
        RC4s(RoutingData):
        +-----------+------+------+-------+--------+
        | SessionID | Lang | Meta | Extra | Length |
        +-----------+------+------+-------+--------+
        |    8      |  1   |  1   |   2   |    4   |
        +-----------+------+------+-------+--------+

    """

    # binary pack all of the passed config values as unsigned numbers
    #   B == 1 byte unsigned char, H == 2 byte unsigned short, L == 4 byte unsigned long
    data = sessionID + struct.pack(
        "=BBHL", LANGUAGE.get(language.upper(), 0), META.get(meta.upper(), 0),
        ADDITIONAL.get(additional.upper(), 0), len(encData))

    # RC4IV = os.urandom(4)
    RC4IV = Random.new().read(4)
    stagingKey = str(stagingKey)
    key = RC4IV + stagingKey
    rc4EncData = encryption.rc4(key, data)

    # return an rc4 encyption of the routing packet, append an HMAC of the packet, then the actual encrypted data
    packet = RC4IV + rc4EncData + encData

    return packet
Beispiel #3
0
def build_routing_packet(stagingKey, sessionID, language, meta="NONE", additional="NONE", encData=''):
    """
    Takes the specified parameters for an RC4 "routing packet" and builds/returns
    an HMAC'ed RC4 "routing packet".

    packet format:

        Routing Packet:
        +---------+-------------------+--------------------------+
        | RC4 IV  | RC4s(RoutingData) | AESc(client packet data) | ... 
        +---------+-------------------+--------------------------+
        |    4    |         16        |        RC4 length        |
        +---------+-------------------+--------------------------+
        
        RC4s(RoutingData):
        +-----------+------+------+-------+--------+
        | SessionID | Lang | Meta | Extra | Length |
        +-----------+------+------+-------+--------+
        |    8      |  1   |  1   |   2   |    4   |
        +-----------+------+------+-------+--------+

    """

    # binary pack all of the passed config values as unsigned numbers
    #   B == 1 byte unsigned char, H == 2 byte unsigned short, L == 4 byte unsigned long
    data = sessionID + struct.pack("=BBHL", LANGUAGE.get(language.upper(), 0), META.get(meta.upper(), 0), ADDITIONAL.get(additional.upper(), 0), len(encData))

    # RC4IV = os.urandom(4)
    RC4IV = Random.new().read(4)
    stagingKey = str(stagingKey)
    key = RC4IV + stagingKey
    rc4EncData = encryption.rc4(key, data)

    # return an rc4 encyption of the routing packet, append an HMAC of the packet, then the actual encrypted data
    packet = RC4IV + rc4EncData + encData

    return packet
Beispiel #4
0
def parse_routing_packet(stagingKey, data):
    """
    Decodes the rc4 "routing packet" and parses raw agent data into:

        {sessionID : (language, meta, additional, [encData]), ...}


    Routing packet format:

        +---------+-------------------+--------------------------+
        | RC4 IV  | RC4s(RoutingData) | AESc(client packet data) | ... 
        +---------+-------------------+--------------------------+
        |    4    |         16        |        RC4 length        |
        +---------+-------------------+--------------------------+
        
        RC4s(RoutingData):
        +-----------+------+------+-------+--------+
        | SessionID | Lang | Meta | Extra | Length |
        +-----------+------+------+-------+--------+
        |    8      |  1   |  1   |   2   |    4   |
        +-----------+------+------+-------+--------+

    """

    if data:
        results = {}
        offset = 0

        # ensure we have at least the 20 bytes for a routing packet
        if len(data) >= 20:

            while True:

                if len(data) - offset < 20:
                    break

                RC4IV = data[0+offset:4+offset]
                RC4data = data[4+offset:20+offset]
                routingPacket = encryption.rc4(RC4IV+stagingKey, RC4data)
                sessionID = routingPacket[0:8]

                # B == 1 byte unsigned char, H == 2 byte unsigned short, L == 4 byte unsigned long
                (language, meta, additional, length) = struct.unpack("=BBHL", routingPacket[8:])
                if length < 0:
                    dispatcher.send('[*] parse_agent_data(): length in decoded rc4 packet is < 0', sender='Packets')
                    encData = None
                else:
                    encData = data[(20+offset):(20+offset+length)]

                results[sessionID] = (LANGUAGE_IDS.get(language, 'NONE'), META_IDS.get(meta, 'NONE'), ADDITIONAL_IDS.get(additional, 'NONE'), encData)

                # check if we're at the end of the packet processing
                remainingData = data[20+offset+length:]
                if not remainingData or remainingData == '':
                    break

                offset += 20 + length

            return results

        else:
            dispatcher.send("[*] parse_agent_data() data length incorrect: %s" % (len(data)), sender='Packets')
            return None

    else:
        dispatcher.send("[*] parse_agent_data() data is None", sender='Packets')
        return None
Beispiel #5
0
def parse_routing_packet(stagingKey, data):
    """
    Decodes the rc4 "routing packet" and parses raw agent data into:

        {sessionID : (language, meta, additional, [encData]), ...}


    Routing packet format:

        +---------+-------------------+--------------------------+
        | RC4 IV  | RC4s(RoutingData) | AESc(client packet data) | ... 
        +---------+-------------------+--------------------------+
        |    4    |         16        |        RC4 length        |
        +---------+-------------------+--------------------------+
        
        RC4s(RoutingData):
        +-----------+------+------+-------+--------+
        | SessionID | Lang | Meta | Extra | Length |
        +-----------+------+------+-------+--------+
        |    8      |  1   |  1   |   2   |    4   |
        +-----------+------+------+-------+--------+

    """

    if data:
        results = {}
        offset = 0

        # ensure we have at least the 20 bytes for a routing packet
        if len(data) >= 20:

            while True:

                if len(data) - offset < 20:
                    break

                RC4IV = data[0+offset:4+offset]
                RC4data = data[4+offset:20+offset]
                routingPacket = encryption.rc4(RC4IV+stagingKey, RC4data)
                sessionID = routingPacket[0:8]

                # B == 1 byte unsigned char, H == 2 byte unsigned short, L == 4 byte unsigned long
                (language, meta, additional, length) = struct.unpack("=BBHL", routingPacket[8:])
                if length < 0:
                    dispatcher.send('[*] parse_agent_data(): length in decoded rc4 packet is < 0', sender='Packets')
                    encData = None
                else:
                    encData = data[(20+offset):(20+offset+length)]

                results[sessionID] = (LANGUAGE_IDS.get(language, 'NONE'), META_IDS.get(meta, 'NONE'), ADDITIONAL_IDS.get(additional, 'NONE'), encData)

                # check if we're at the end of the packet processing
                remainingData = data[20+offset+length:]
                if not remainingData or remainingData == '':
                    break

                offset += 20 + length

            return results

        else:
            dispatcher.send("[*] parse_agent_data() data length incorrect: %s" % (len(data)), sender='Packets')
            return None

    else:
        dispatcher.send("[*] parse_agent_data() data is None", sender='Packets')
        return None