Beispiel #1
0
/* Read a string prefixed by 1 byte size
 * Size  String-------------
 * 0x04  0x41 0x42 0x42 0x40
 */
static enum proto_parse_status cursor_read_variable_string(struct cursor *cursor, char **out_str, unsigned *out_str_len)
{
    unsigned str_len;
    CHECK(1);
    str_len = cursor_read_u8(cursor);
    SLOG(LOG_DEBUG, "Reading variable str of length %d", str_len);
    if (out_str_len) *out_str_len = str_len;
    return cursor_read_fixed_string(cursor, out_str, str_len);
}
Beispiel #2
0
static enum proto_parse_status tns_parse_sql_query_jdbc(struct sql_proto_info *info, struct cursor *cursor)
{
    SLOG(LOG_DEBUG, "Parsing a jdbc query");
    enum proto_parse_status status;

    DROP_FIX(cursor, 1);

    uint_least64_t sql_len;
    status = cursor_read_variable_int(cursor, &sql_len);
    if (status != PROTO_OK) return status;
    SLOG(LOG_DEBUG, "Size sql %zu", sql_len);

    DROP_FIX(cursor, 1);
    // We have a number of fields at the end of the query
    uint_least64_t end_len;
    status = cursor_read_variable_int(cursor, &end_len);
    if (status != PROTO_OK) return status;

    DROP_FIX(cursor, 2);
    DROP_VARS(cursor, 3);
    DROP_FIX(cursor, 1);
    DROP_VAR(cursor);
    DROP_FIX(cursor, 6);
    DROP_VAR(cursor);

    char *sql = "";
    if (sql_len > 0) {
        // Some unknown bytes
        while (cursor->cap_len > 1 && !isprint(cursor_peek_u8(cursor, 1))) {
            cursor_drop(cursor, 1);
        }

        CHECK(1);
        if (sql_len > 0xff && 0xff == cursor_peek_u8(cursor, 0)) {
            SLOG(LOG_DEBUG, "Looks like prefixed length chunks of size 0xff...");
            status = cursor_read_chunked_string(cursor, &sql, 0xff);
        } else if (sql_len > 0x40 && 0x40 == cursor_peek_u8(cursor, 1)) {
            SLOG(LOG_DEBUG, "Looks like prefixed length chunks of size 0x40...");
            cursor_drop(cursor, 1);
            status = cursor_read_chunked_string(cursor, &sql, 0x40);
        } else {
            if (!isprint(cursor_peek_u8(cursor, 0))) {
                cursor_drop(cursor, 1);
            }
            SLOG(LOG_DEBUG, "Looks like a fixed string of size %zu", sql_len);
            status = cursor_read_fixed_string(cursor, &sql, sql_len);
        }
        if (status != PROTO_OK) return status;
    }
    SLOG(LOG_DEBUG, "Sql parsed: %s", sql);
    sql_set_query(info, "%s", sql);

    SLOG(LOG_DEBUG, "Skipping %zu end variable fields", end_len);
    DROP_VARS(cursor, end_len);
    return PROTO_OK;
}
Beispiel #3
0
/* Read a string prefixed by 1 byte size
 * Size  String-------------
 * 0x04  0x41 0x42 0x42 0x40
 */
static enum proto_parse_status cursor_read_variable_string(struct cursor *cursor,
        char *buf, size_t size_buf, unsigned *out_str_len)
{
    unsigned str_len;
    CHECK(1);
    str_len = cursor_read_u8(cursor);
    SLOG(LOG_DEBUG, "Reading variable str of length %d", str_len);
    if (out_str_len) *out_str_len = str_len;
    int ret = cursor_read_fixed_string(cursor, buf, size_buf, str_len);
    if (ret == -1) return PROTO_TOO_SHORT;
    else return PROTO_OK;
}
Beispiel #4
0
static enum proto_parse_status tns_parse_sql_query_oci(struct sql_proto_info *info, struct cursor *cursor)
{
    SLOG(LOG_DEBUG, "Parsing an oci query");
    uint8_t query_size = parse_query_header(cursor);
    struct query_candidate candidate = {.num_candidate_size = 0};
    if (query_size > 0) {
        candidate.candidate_sizes[candidate.num_candidate_size++] = query_size;
    }

    bool has_query = lookup_query(cursor, &candidate);
    info->u.query.sql[0] = '\0';
    info->u.query.truncated = 0;
    if (has_query) {
        SLOG(LOG_DEBUG, "Found a query, parsing it");
        if (candidate.is_chunked) {
            cursor_read_chunked_string(cursor, info->u.query.sql, sizeof(info->u.query.sql), MAX_OCI_CHUNK);
        } else {
            cursor_read_fixed_string(cursor, info->u.query.sql, sizeof(info->u.query.sql), candidate.query_size);
        }
    }
    SLOG(LOG_DEBUG, "Sql parsed: %s", info->u.query.sql);
    info->set_values |= SQL_SQL;
    // Drop the rest
    if(cursor->cap_len > 0) cursor_drop(cursor, cursor->cap_len - 1);
    return PROTO_OK;
}

/*
 * | 1 byte | 1 + 0-8 bytes | 1 byte | 1 + 0-4 bytes  | Lots of unknown bytes | variable  |
 * | Unk    | Sql len       | Unk    | Num end fields | Unk                   | sql query |
 */
static enum proto_parse_status tns_parse_sql_query_jdbc(struct sql_proto_info *info, struct cursor *cursor)
{
    SLOG(LOG_DEBUG, "Parsing a jdbc query");
    enum proto_parse_status status = PROTO_OK;

    DROP_FIX(cursor, 1);

    uint_least64_t sql_len;
    if (PROTO_OK != (status = cursor_read_variable_int(cursor, &sql_len))) return status;
    SLOG(LOG_DEBUG, "Size sql %zu", sql_len);

    DROP_FIX(cursor, 1);
    DROP_VAR(cursor);
    DROP_FIX(cursor, 2);

    info->u.query.sql[0] = '\0';
    info->u.query.truncated = 0; // TODO Handle truncated
    if (sql_len > 0) {
        // Some unknown bytes
        while (cursor->cap_len > 1 && PROTO_OK != is_range_print(cursor, MIN(MIN_QUERY_SIZE, sql_len), 1)) {
            // TODO drop to the first non printable
            cursor_drop(cursor, 1);
        }
        CHECK(1);
        if (sql_len > 0xff && 0xff == cursor_peek_u8(cursor, 0)) {
            SLOG(LOG_DEBUG, "Looks like prefixed length chunks of size 0xff...");
            status = cursor_read_chunked_string(cursor, info->u.query.sql, sizeof(info->u.query.sql), 0xff);
        } else if (sql_len > MAX_OCI_CHUNK && MAX_OCI_CHUNK == cursor_peek_u8(cursor, 0)) {
            SLOG(LOG_DEBUG, "Looks like prefixed length chunks of size 0x40...");
            status = cursor_read_chunked_string(cursor, info->u.query.sql, sizeof(info->u.query.sql),
                    MAX_OCI_CHUNK);
        } else {
            // We don't care about the first non printable character
            cursor_drop(cursor, 1);
            CHECK(1);
            // In rare occurrence where sql_len == first character, we check the byte after the expected query,
            // if it's printable, the first character is probably the prefixed size.
            if (cursor_peek_u8(cursor, 0) == sql_len && sql_len < cursor->cap_len && is_print(cursor_peek_u8(cursor, sql_len)))
                cursor_drop(cursor, 1);
            SLOG(LOG_DEBUG, "Looks like a fixed string of size %zu", sql_len);
            int written_bytes = cursor_read_fixed_string(cursor, info->u.query.sql,
                    sizeof(info->u.query.sql), sql_len);
            if (written_bytes < 0) return PROTO_TOO_SHORT;
        }
        if (status != PROTO_OK) return status;
    }
    SLOG(LOG_DEBUG, "Sql parsed: %s", info->u.query.sql);
    info->set_values |= SQL_SQL;

    return PROTO_OK;
}