Ejemplo n.º 1
0
/**
 * Store a field in the agent list
 *
 * Creates a new field and adds it to the agent list field list.
 *
 * @param[in] ib IronBee object
 * @param[in,out] mp Memory pool to allocate from
 * @param[in] agent_list Field to add the field to
 * @param[in] name Field name
 * @param[in] value Field value
 *
 * @returns Status code
 */
static ib_status_t modua_store_field(ib_engine_t *ib,
                                     ib_mpool_t *mp,
                                     ib_field_t *agent_list,
                                     const char *name,
                                     const char *value)
{
    IB_FTRACE_INIT();
    ib_field_t *tmp_field = NULL;
    ib_status_t rc = IB_OK;

    /* No value?  Do nothing */
    if (value == NULL) {
        ib_log_debug3(ib, "No %s field in user agent", name);
        IB_FTRACE_RET_STATUS(IB_OK);
    }

    /* Create the field */
    rc = ib_field_create(
        &tmp_field,
        mp,
        IB_FIELD_NAME(name),
        IB_FTYPE_NULSTR,
        ib_ftype_nulstr_in(value)
    );
    if (rc != IB_OK) {
        ib_log_alert(ib,
                     "Error creating user agent %s field: %s", name, ib_status_to_string(rc));
        IB_FTRACE_RET_STATUS(rc);
    }

    /* Add the field to the list */
    rc = ib_field_list_add(agent_list, tmp_field);
    if (rc != IB_OK) {
        ib_log_alert(ib,
                     "Error adding user agent %s field: %s", name, ib_status_to_string(rc));
        IB_FTRACE_RET_STATUS(rc);
    }

    ib_log_debug3(ib, "Stored user agent %s '%s'", name, value);

    IB_FTRACE_RET_STATUS(IB_OK);
}
Ejemplo n.º 2
0
/**
 * Lookup the IP address in the GeoIP database
 *
 * @param[in] ib IronBee engine
 * @param[in] tx Transaction
 * @param[in] event Event
 * @param[in] data callback data (Module configuration)
 */
static ib_status_t geoip_lookup(
    ib_engine_t *ib,
    ib_tx_t *tx,
    ib_state_event_type_t event,
    void *data
)
{
    assert(ib != NULL);
    assert(event == handle_context_tx_event);
    assert(data != NULL);

    const char *ip = tx->er_ipstr;
    const module_data_t *mod_data = (const module_data_t *)data;

    if (ip == NULL) {
        ib_log_alert_tx(tx, "Trying to lookup NULL IP in GEOIP");
        return IB_EINVAL;
    }

#ifdef GEOIP_HAVE_VERSION
    /**
     * Some configurations exist as single characters and must be converted to
     * a string. This is simply a place to assemble that string before
     * it is passed into ip_data_add_nulstr.
     * This is only needed if we have support confidence items. WAM
     */
    char one_char_str[2] = { '\0', '\0' };
#endif /* GEOIP_HAVE_VERSION */

    ib_status_t rc;

    /* Declare and initialize the GeoIP property list.
     * Regardless of if we find a record or not, we want to create the list
     * artifact so that later modules know we ran and did [not] find a
     * record. */
    ib_field_t *geoip_lst = NULL;

    ib_field_t *tmp_field = NULL;

    /* Id of geo ip record to read. */
    int geoip_id;

    ib_log_debug_tx(tx, "GeoIP Lookup '%s'", ip);

    /* Build a new list. */
    rc = ib_var_source_initialize(
        mod_data->geoip_source,
        &geoip_lst,
        tx->var_store,
        IB_FTYPE_LIST
    );

    /* NOTICE: Called before GeoIP_record_by_addr allocates a
     * GeoIPRecord. */
    if (rc != IB_OK) {
        ib_log_alert_tx(tx, "Unable to add GEOIP var.");
        return IB_EINVAL;
    }

    if (mod_data->geoip_db == NULL) {
        ib_log_alert_tx(tx,
                        "GeoIP database was never opened. Perhaps the "
                        "configuration file needs a GeoIPDatabaseFile "
                        "\"/usr/share/geoip/GeoLite.dat\" line?");
        return IB_EINVAL;
    }

    geoip_id = GeoIP_id_by_addr(mod_data->geoip_db, ip);

    if (geoip_id > 0) {
        const char *tmp_str;

        ib_log_debug_tx(tx, "GeoIP record found.");

        /* Add integers. */
        tmp_field = NULL;

        tmp_str = GeoIP_code_by_id(geoip_id);
        if (tmp_str)
        {
            ib_field_create(&tmp_field,
                            tx->mp,
                            IB_FIELD_NAME("country_code"),
                            IB_FTYPE_NULSTR,
                            ib_ftype_nulstr_in(tmp_str));
            ib_field_list_add(geoip_lst, tmp_field);
        }

        tmp_str = GeoIP_code3_by_id(geoip_id);
        if (tmp_str)
        {
            ib_field_create(&tmp_field,
                            tx->mp,
                            IB_FIELD_NAME("country_code3"),
                            IB_FTYPE_NULSTR,
                            ib_ftype_nulstr_in(tmp_str));
            ib_field_list_add(geoip_lst, tmp_field);
        }

        tmp_str = GeoIP_country_name_by_id(mod_data->geoip_db, geoip_id);
        if (tmp_str)
        {
            ib_field_create(&tmp_field,
                            tx->mp,
                            IB_FIELD_NAME("country_name"),
                            IB_FTYPE_NULSTR,
                            ib_ftype_nulstr_in(tmp_str));
            ib_field_list_add(geoip_lst, tmp_field);
        }

        tmp_str = GeoIP_continent_by_id(geoip_id);
        if (tmp_str)
        {
            ib_field_create(&tmp_field,
                            tx->mp,
                            IB_FIELD_NAME("continent_code"),
                            IB_FTYPE_NULSTR,
                            ib_ftype_nulstr_in(tmp_str));
            ib_field_list_add(geoip_lst, tmp_field);
        }
    }
    else
    {
        ib_log_debug_tx(tx, "No GeoIP record found.");
        ib_field_create(&tmp_field,
                        tx->mp,
                        IB_FIELD_NAME("country_code"),
                        IB_FTYPE_NULSTR,
                        ib_ftype_nulstr_in("O1"));
        ib_field_list_add(geoip_lst, tmp_field);
        ib_field_create(&tmp_field,
                        tx->mp,
                        IB_FIELD_NAME("country_code3"),
                        IB_FTYPE_NULSTR,
                        ib_ftype_nulstr_in("O01"));
        ib_field_list_add(geoip_lst, tmp_field);
        ib_field_create(&tmp_field,
                        tx->mp,
                        IB_FIELD_NAME("country_name"),
                        IB_FTYPE_NULSTR,
                        ib_ftype_nulstr_in("Other Country"));
        ib_field_list_add(geoip_lst, tmp_field);
        ib_field_create(&tmp_field,
                        tx->mp,
                        IB_FIELD_NAME("continent_code"),
                        IB_FTYPE_NULSTR,
                        ib_ftype_nulstr_in("O1"));
        ib_field_list_add(geoip_lst, tmp_field);
    }

    return IB_OK;
}
Ejemplo n.º 3
0
/**
 * Length transformation
 *
 * @param[in] ib IronBee engine
 * @param[in] mp Memory pool to use for allocations.
 * @param[in] fndata Function specific data.
 * @param[in] fin Input field.
 * @param[out] fout Output field.
 * @param[out] pflags Transformation flags.
 *
 * @returns IB_OK if successful.
 */
static ib_status_t tfn_length(ib_engine_t *ib,
                              ib_mpool_t *mp,
                              void *fndata,
                              const ib_field_t *fin,
                              ib_field_t **fout,
                              ib_flags_t *pflags)
{
    ib_status_t rc = IB_OK;

    assert(mp != NULL);
    assert(fin != NULL);
    assert(fout != NULL);
    assert(pflags != NULL);

    /**
     * This works on C-style (NUL terminated) and byte strings.  Note
     * that data is assumed to be a NUL terminated string (because our
     * configuration parser can't produce anything else).
     **/
    if (fin->type == IB_FTYPE_NULSTR) {
        const char *fval;
        rc = ib_field_value(fin, ib_ftype_nulstr_out(&fval));
        if (rc != IB_OK) {
            return rc;
        }

        const ib_num_t len = strlen(fval);
        rc = ib_field_create(
            fout, mp,
            IB_FIELD_NAME("Length"),
            IB_FTYPE_NUM,
            ib_ftype_num_in(&len)
        );
    }
    else if (fin->type == IB_FTYPE_BYTESTR) {
        const ib_bytestr_t *value;
        rc = ib_field_value(fin, ib_ftype_bytestr_out(&value));
        if (rc != IB_OK) {
            return rc;
        }

        const ib_num_t len = ib_bytestr_length(value);
        rc = ib_field_create(
            fout, mp,
            IB_FIELD_NAME("Length"),
            IB_FTYPE_NUM,
            ib_ftype_num_in(&len)
        );
    }
    else if (fin->type == IB_FTYPE_LIST) {
        const ib_list_node_t  *node = NULL;
        const ib_list_t       *ilist;        /** Incoming list */

        /* Get the incoming list */
        // @todo Remove mutable once list is const correct.
        rc = ib_field_value(fin, ib_ftype_list_out(&ilist));
        if (rc != IB_OK) {
            return rc;
        }

        if (ilist == NULL) {
            return IB_EUNKNOWN;
        }

        /* Create the outgoing list field */
        rc = ib_field_create(
            fout, mp,
            IB_FIELD_NAME("Length"),
            IB_FTYPE_LIST, NULL
        );
        if (rc != IB_OK) {
            return rc;
        }

        /* Walk through the incoming fields */
        IB_LIST_LOOP_CONST(ilist, node) {
            const ib_field_t *ifield = (ib_field_t *)node->data;
            ib_field_t *ofield = NULL;
            ib_flags_t flags = 0;

            rc = tfn_length(ib, mp, NULL, ifield, &ofield, &flags);
            if (rc != IB_OK) {
                return rc;
            }
            rc = ib_field_list_add(*fout, ofield);
            if (rc != IB_OK) {
                return rc;
            }
        }
    }
    else {
Ejemplo n.º 4
0
/*
 * Callback used to generate request header fields.
 */
static ib_status_t core_gen_request_header_fields(ib_engine_t *ib,
                                                  ib_tx_t *tx,
                                                  ib_state_event_type_t event,
                                                  void *cbdata)
{
    ib_field_t *f;
    ib_status_t rc;

    assert(ib != NULL);
    assert(tx != NULL);
    assert(event == request_header_finished_event);

    /**
     * Alias connection remote and server addresses
     */

    rc = ib_data_get(tx->conn->data, "server_addr", &f);
    if (rc != IB_OK) {
        return rc;
    }
    rc = ib_data_add(tx->data, f);
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_data_get(tx->conn->data, "server_port", &f);
    if (rc != IB_OK) {
        return rc;
    }
    rc = ib_data_add(tx->data, f);
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_data_get(tx->conn->data, "remote_addr", &f);
    if (rc != IB_OK) {
        return rc;
    }
    rc = ib_data_add(tx->data, f);
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_data_get(tx->conn->data, "remote_port", &f);
    if (rc != IB_OK) {
        return rc;
    }
    rc = ib_data_add(tx->data, f);
    if (rc != IB_OK) {
        return rc;
    }

    core_gen_tx_numeric_field(tx, "conn_tx_count",
                              tx->conn->tx_count);

    if (tx->request_line != NULL) {
        core_gen_tx_bytestr_alias_field(tx, "request_line",
                                        tx->request_line->raw);

        core_gen_tx_bytestr_alias_field(tx, "request_method",
                                        tx->request_line->method);

        core_gen_tx_bytestr_alias_field(tx, "request_uri_raw",
                                        tx->request_line->uri);

        core_gen_tx_bytestr_alias_field(tx, "request_protocol",
                                        tx->request_line->protocol);
    }

    /* Populate the ARGS collection. */
    rc = ib_data_get(tx->data, "ARGS", &f);
    if (rc == IB_OK) {
        ib_field_t *param_list;

        /* Add request URI parameters to ARGS collection. */
        rc = ib_data_get(tx->data, "request_uri_params", &param_list);
        if (rc == IB_OK) {
            ib_list_t *field_list;
            ib_list_node_t *node = NULL;

            rc = ib_field_mutable_value(
                param_list,
                ib_ftype_list_mutable_out(&field_list)
            );
            if (rc != IB_OK) {
                return rc;
            }

            IB_LIST_LOOP(field_list, node) {
                ib_field_t *param = (ib_field_t *)ib_list_node_data(node);

                /* Add the field to the ARGS collection. */
                rc = ib_field_list_add(f, param);
                if (rc != IB_OK) {
                    ib_log_notice_tx(tx,
                                     "Failed to add parameter to "
                                     "ARGS collection: %s",
                                     ib_status_to_string(rc));
                }
            }
Ejemplo n.º 5
0
static
ib_status_t sqli_op_execute(
    ib_tx_t *tx,
    const ib_field_t *field,
    ib_field_t *capture,
    ib_num_t *result,
    void *instance_data,
    void *cbdata
)
{
    assert(tx     != NULL);
    assert(field  != NULL);
    assert(result != NULL);

    const sqli_fingerprint_set_t *ps = (const sqli_fingerprint_set_t *)instance_data;
    sfilter                   sf;
    ib_bytestr_t             *bs;
    ib_status_t               rc;
    sqli_callback_data_t      callback_data;

    *result = 0;

    /* Currently only bytestring types are supported.
     * Other types will just get passed through. */
    if (field->type != IB_FTYPE_BYTESTR) {
        return IB_OK;
    }

    rc = ib_field_value(field, ib_ftype_bytestr_mutable_out(&bs));
    if (rc != IB_OK) {
        return rc;
    }

    /* Run through libinjection. */
    libinjection_sqli_init(
        &sf,
        (const char *)ib_bytestr_const_ptr(bs),
        ib_bytestr_length(bs),
        FLAG_NONE
    );
    callback_data.confidence = 0;
    callback_data.fingerprint_set = NULL;
    if (ps != NULL) {
        callback_data.fingerprint_set = ps;
        libinjection_sqli_callback(&sf, sqli_lookup_word, (void *)&callback_data);
    }
    if (libinjection_is_sqli(&sf)) {
        ib_log_debug_tx(tx, "Matched SQLi fingerprint: %s", sf.fingerprint);
        *result = 1;
    }
    if (*result == 1 && capture != NULL) {
        {
            ib_field_t *fingerprint_field;
            size_t fingerprint_length = strlen(sf.fingerprint);
            const uint8_t *fingerprint;

            fingerprint = ib_mm_memdup(
                tx->mm,
                sf.fingerprint, fingerprint_length
            );
            if (fingerprint == NULL) {
                return IB_EALLOC;
            }

            rc = ib_field_create_bytestr_alias(
                &fingerprint_field,
                tx->mm,
                IB_S2SL("fingerprint"),
                fingerprint, fingerprint_length
            );
            if (rc != IB_OK) {
                return rc;
            }

            rc = ib_field_list_add(capture, fingerprint_field);
            if (rc != IB_OK) {
                return rc;
            }
        }

        {
            ib_field_t *confidence_field;

            rc = ib_field_create(
                &confidence_field,
                tx->mm,
                IB_S2SL("confidence"),
                IB_FTYPE_NUM,
                ib_ftype_num_in(&callback_data.confidence)
            );
            if (rc != IB_OK) {
                return rc;
            }

            rc = ib_field_list_add(capture, confidence_field);
            if (rc != IB_OK) {
                return rc;
            }
        }
    }

    return IB_OK;
}
Ejemplo n.º 6
0
/*
 * Callback used to generate request header fields.
 */
static ib_status_t core_gen_request_header_fields(ib_engine_t *ib,
        ib_tx_t *tx,
        ib_state_event_type_t event,
        void *cbdata)
{
    ib_field_t *f;
    ib_status_t rc;
    ib_conn_t *conn = tx->conn;

    assert(ib != NULL);
    assert(tx != NULL);
    assert(event == handle_request_header_event);

    core_gen_tx_bytestr_alias2(tx, "server_addr",
                               conn->local_ipstr,
                               strlen(conn->local_ipstr));

    core_gen_tx_numeric(tx, "server_port", conn->local_port);

    core_gen_tx_bytestr_alias2(tx, "remote_addr",
                               conn->remote_ipstr,
                               strlen(conn->remote_ipstr));


    core_gen_tx_numeric(tx, "remote_port", conn->remote_port);

    core_gen_tx_numeric(tx, "conn_tx_count",
                        tx->conn->tx_count);

    if (tx->request_line != NULL) {
        core_gen_tx_bytestr_alias(tx, "request_line",
                                  tx->request_line->raw);

        core_gen_tx_bytestr_alias(tx, "request_method",
                                  tx->request_line->method);

        core_gen_tx_bytestr_alias(tx, "request_uri_raw",
                                  tx->request_line->uri);

        core_gen_tx_bytestr_alias(tx, "request_protocol",
                                  tx->request_line->protocol);
    }

    /* Populate the ARGS collection. */
    rc = core_slow_get(&f, tx, "ARGS");
    if (rc == IB_OK) {
        ib_field_t *param_list;

        rc = core_slow_get(&param_list, tx, "request_uri_params");
        if (rc == IB_OK) {
            ib_list_t *field_list;
            ib_list_node_t *node = NULL;

            rc = ib_field_mutable_value(
                     param_list,
                     ib_ftype_list_mutable_out(&field_list)
                 );
            if (rc != IB_OK) {
                return rc;
            }

            IB_LIST_LOOP(field_list, node) {
                ib_field_t *param = (ib_field_t *)ib_list_node_data(node);

                /* Add the field to the ARGS collection. */
                rc = ib_field_list_add(f, param);
                if (rc != IB_OK) {
                    ib_log_notice_tx(tx,
                                     "Failed to add parameter to "
                                     "ARGS collection: %s",
                                     ib_status_to_string(rc));
                }
            }