Ejemplo n.º 1
0
 def testIntToFlowId(self):
     self.assertEqual(db_utils.IntToFlowID(1), "00000001")
     self.assertEqual(db_utils.IntToFlowID(0x1234ABCD), "1234ABCD")
     self.assertEqual(db_utils.IntToFlowID(0xFFFFFFFF), "FFFFFFFF")
     self.assertEqual(db_utils.IntToFlowID(0x100000000), "0000000100000000")
     self.assertEqual(db_utils.IntToFlowID(0xFFFFFFFFFFFFFFFF),
                      "FFFFFFFFFFFFFFFF")
Ejemplo n.º 2
0
    def ReadHuntOutputPluginLogEntries(self,
                                       hunt_id,
                                       output_plugin_id,
                                       offset,
                                       count,
                                       with_type=None,
                                       cursor=None):
        """Reads hunt output plugin log entries."""
        query = ("SELECT client_id, flow_id, log_entry_type, message, "
                 "UNIX_TIMESTAMP(timestamp) "
                 "FROM flow_output_plugin_log_entries "
                 "FORCE INDEX (flow_output_plugin_log_entries_by_hunt) "
                 "WHERE hunt_id = %s AND output_plugin_id = %s ")
        args = [
            db_utils.HuntIDToInt(hunt_id),
            db_utils.OutputPluginIDToInt(output_plugin_id)
        ]

        if with_type is not None:
            query += "AND log_entry_type = %s "
            args.append(int(with_type))

        query += "ORDER BY log_id ASC LIMIT %s OFFSET %s"
        args.append(count)
        args.append(offset)

        cursor.execute(query, args)

        ret = []
        for (client_id_int, flow_id_int, log_entry_type, message,
             timestamp) in cursor.fetchall():
            ret.append(
                rdf_flow_objects.FlowOutputPluginLogEntry(
                    hunt_id=hunt_id,
                    client_id=db_utils.IntToClientID(client_id_int),
                    flow_id=db_utils.IntToFlowID(flow_id_int),
                    output_plugin_id=output_plugin_id,
                    log_entry_type=log_entry_type,
                    message=message,
                    timestamp=mysql_utils.TimestampToRDFDatetime(timestamp)))

        return ret
Ejemplo n.º 3
0
    def ReadHuntLogEntries(self,
                           hunt_id,
                           offset,
                           count,
                           with_substring=None,
                           cursor=None):
        """Reads hunt log entries of a given hunt using given query options."""
        hunt_id_int = db_utils.HuntIDToInt(hunt_id)

        query = (
            "SELECT client_id, flow_id, message, UNIX_TIMESTAMP(timestamp) "
            "FROM flow_log_entries "
            "FORCE INDEX(flow_log_entries_by_hunt) "
            "WHERE hunt_id = %s AND flow_id = hunt_id ")

        args = [hunt_id_int]

        if with_substring is not None:
            query += "AND message LIKE %s "
            args.append("%" + db_utils.EscapeWildcards(with_substring) + "%")

        query += "ORDER BY timestamp ASC LIMIT %s OFFSET %s"

        args.append(count)
        args.append(offset)

        cursor.execute(query, args)

        flow_log_entries = []
        for client_id_int, flow_id_int, message, timestamp in cursor.fetchall(
        ):
            flow_log_entries.append(
                rdf_flow_objects.FlowLogEntry(
                    client_id=db_utils.IntToClientID(client_id_int),
                    flow_id=db_utils.IntToFlowID(flow_id_int),
                    hunt_id=hunt_id,
                    message=message,
                    timestamp=mysql_utils.TimestampToRDFDatetime(timestamp)))

        return flow_log_entries
Ejemplo n.º 4
0
    def ReadHuntClientResourcesStats(self, hunt_id, cursor=None):
        """Read/calculate hunt client resources stats."""
        hunt_id_int = db_utils.HuntIDToInt(hunt_id)

        query = """
      SELECT
        COUNT(*),
        SUM(user_cpu_time_used_micros),
        SUM((user_cpu_time_used_micros) * (user_cpu_time_used_micros)),
        SUM(system_cpu_time_used_micros),
        SUM((system_cpu_time_used_micros) * (system_cpu_time_used_micros)),
        SUM(network_bytes_sent),
        SUM(network_bytes_sent * network_bytes_sent),
    """

        scaled_bins = [
            int(1000000 * b)
            for b in rdf_stats.ClientResourcesStats.CPU_STATS_BINS
        ]

        query += self._BinsToQuery(scaled_bins, "(user_cpu_time_used_micros)")
        query += ","
        query += self._BinsToQuery(scaled_bins,
                                   "(system_cpu_time_used_micros)")
        query += ","
        query += self._BinsToQuery(
            rdf_stats.ClientResourcesStats.NETWORK_STATS_BINS,
            "network_bytes_sent")

        query += " FROM flows "
        query += "FORCE INDEX(flows_by_hunt) "
        query += "WHERE parent_hunt_id = %s AND parent_flow_id IS NULL"

        cursor.execute(query, [hunt_id_int])

        response = cursor.fetchone()
        (count, user_sum, user_sq_sum, system_sum, system_sq_sum, network_sum,
         network_sq_sum) = response[:7]

        stats = rdf_stats.ClientResourcesStats(
            user_cpu_stats=rdf_stats.RunningStats(
                num=count,
                sum=db_utils.MicrosToSeconds(int(user_sum or 0)),
                sum_sq=int(user_sq_sum or 0) / 1e12,
            ),
            system_cpu_stats=rdf_stats.RunningStats(
                num=count,
                sum=db_utils.MicrosToSeconds(int(system_sum or 0)),
                sum_sq=int(system_sq_sum or 0) / 1e12,
            ),
            network_bytes_sent_stats=rdf_stats.RunningStats(
                num=count,
                sum=float(network_sum or 0),
                sum_sq=float(network_sq_sum or 0),
            ),
        )

        offset = 7
        stats.user_cpu_stats.histogram = rdf_stats.StatsHistogram()
        for b_num, b_max_value in zip(
                response[offset:],
                rdf_stats.ClientResourcesStats.CPU_STATS_BINS):
            stats.user_cpu_stats.histogram.bins.append(
                rdf_stats.StatsHistogramBin(range_max_value=b_max_value,
                                            num=b_num))

        offset += len(rdf_stats.ClientResourcesStats.CPU_STATS_BINS)
        stats.system_cpu_stats.histogram = rdf_stats.StatsHistogram()
        for b_num, b_max_value in zip(
                response[offset:],
                rdf_stats.ClientResourcesStats.CPU_STATS_BINS):
            stats.system_cpu_stats.histogram.bins.append(
                rdf_stats.StatsHistogramBin(range_max_value=b_max_value,
                                            num=b_num))

        offset += len(rdf_stats.ClientResourcesStats.CPU_STATS_BINS)
        stats.network_bytes_sent_stats.histogram = rdf_stats.StatsHistogram()
        for b_num, b_max_value in zip(
                response[offset:],
                rdf_stats.ClientResourcesStats.NETWORK_STATS_BINS):
            stats.network_bytes_sent_stats.histogram.bins.append(
                rdf_stats.StatsHistogramBin(range_max_value=b_max_value,
                                            num=b_num))

        query = """
      SELECT
        client_id, flow_id, user_cpu_time_used_micros,
        system_cpu_time_used_micros, network_bytes_sent
      FROM flows
      FORCE INDEX(flows_by_hunt)
      WHERE parent_hunt_id = %s AND parent_flow_id IS NULL AND
            (user_cpu_time_used_micros > 0 OR
             system_cpu_time_used_micros > 0 OR
             network_bytes_sent > 0)
      ORDER BY (user_cpu_time_used_micros + system_cpu_time_used_micros) DESC
      LIMIT 10
    """

        cursor.execute(query, [hunt_id_int])

        for cid, fid, ucpu, scpu, nbs in cursor.fetchall():
            client_id = db_utils.IntToClientID(cid)
            flow_id = db_utils.IntToFlowID(fid)
            stats.worst_performers.append(
                rdf_client_stats.ClientResources(
                    client_id=client_id,
                    session_id=rdfvalue.RDFURN(client_id).Add(flow_id),
                    cpu_usage=rdf_client_stats.CpuSeconds(
                        user_cpu_time=db_utils.MicrosToSeconds(ucpu),
                        system_cpu_time=db_utils.MicrosToSeconds(scpu),
                    ),
                    network_bytes_sent=nbs))

        return stats
Ejemplo n.º 5
0
    def ReadHuntResults(self,
                        hunt_id,
                        offset,
                        count,
                        with_tag=None,
                        with_type=None,
                        with_substring=None,
                        with_timestamp=None,
                        cursor=None):
        """Reads hunt results of a given hunt using given query options."""
        hunt_id_int = db_utils.HuntIDToInt(hunt_id)

        query = ("SELECT client_id, flow_id, hunt_id, payload, type, "
                 "UNIX_TIMESTAMP(timestamp), tag "
                 "FROM flow_results "
                 "FORCE INDEX(flow_results_hunt_id_flow_id_timestamp) "
                 "WHERE hunt_id = %s ")

        args = [hunt_id_int]

        if with_tag:
            query += "AND tag = %s "
            args.append(with_tag)

        if with_type:
            query += "AND type = %s "
            args.append(with_type)

        if with_substring:
            query += "AND payload LIKE %s "
            args.append("%" + db_utils.EscapeWildcards(with_substring) + "%")

        if with_timestamp:
            query += "AND timestamp = FROM_UNIXTIME(%s) "
            args.append(mysql_utils.RDFDatetimeToTimestamp(with_timestamp))

        query += "ORDER BY timestamp ASC LIMIT %s OFFSET %s"
        args.append(count)
        args.append(offset)

        cursor.execute(query, args)

        ret = []
        for (
                client_id_int,
                flow_id_int,
                hunt_id_int,
                serialized_payload,
                payload_type,
                timestamp,
                tag,
        ) in cursor.fetchall():
            if payload_type in rdfvalue.RDFValue.classes:
                payload = rdfvalue.RDFValue.classes[
                    payload_type].FromSerializedBytes(serialized_payload)
            else:
                payload = rdf_objects.SerializedValueOfUnrecognizedType(
                    type_name=payload_type, value=serialized_payload)

            result = rdf_flow_objects.FlowResult(
                client_id=db_utils.IntToClientID(client_id_int),
                flow_id=db_utils.IntToFlowID(flow_id_int),
                hunt_id=hunt_id,
                payload=payload,
                timestamp=mysql_utils.TimestampToRDFDatetime(timestamp))
            if tag is not None:
                result.tag = tag

            ret.append(result)

        return ret