Esempio n. 1
0
int mysql_parser(MolochSession_t *session, void *uw, const unsigned char *data, int len) 
{
    Info_t *info = uw;
    if (session->which != 0) {
        return 0;
    }

    if (len < 37 || data[1] != 0 || data[2] != 0 || data[3] != 1) {
        moloch_parsers_unregister(session, info);
        return 0;
    }

    unsigned char *ptr = (unsigned char*)data + 36;
    unsigned char *end = (unsigned char*)data + len;

    while (ptr < end) {
        if (*ptr == 0)
            break;
        if (!isprint(*ptr)) {
            moloch_parsers_unregister(session, info);
            return 0;
        }
        ptr++;
    }

    moloch_nids_add_protocol(session, "mysql");
    moloch_field_string_add(versionField, session, info->version, info->versionLen, FALSE);
    info->version = 0;

    char *lower = g_ascii_strdown((char *)data+36, ptr - (data + 36));
    moloch_field_string_add(userField, session, lower, ptr - (data + 36), FALSE);

    moloch_parsers_unregister(session, info);
    return 0;
}
Esempio n. 2
0
File: http.c Progetto: Amelos/moloch
int http_parse(MolochSession_t *session, void *uw, const unsigned char *data, int remaining, int which)
{
    HTTPInfo_t            *http          = uw;

    http->which = which;
#ifdef HTTPDEBUG
    LOG("HTTPDEBUG: enter %d - %d %.*s", http->which, remaining, remaining, data);
#endif

    if ((http->wParsers & (1 << http->which)) == 0) {
        return 0;
    }

    while (remaining > 0) {
        int len = http_parser_execute(&http->parsers[http->which], &parserSettings, (char *)data, remaining);
#ifdef HTTPDEBUG
            LOG("HTTPDEBUG: parse result: %d input: %d errno: %d", len, remaining, http->parsers[http->which].http_errno);
#endif
        if (len <= 0) {
            http->wParsers &= ~(1 << http->which);
            if (http->wParsers) {
                moloch_parsers_unregister(session, uw);
            }
            break;
        }
        data += len;
        remaining -= len;
    }
    return 0;
}
Esempio n. 3
0
File: tds.c Progetto: IFGHou/moloch
LOCAL int tds_parser(MolochSession_t *session, void *uw, const unsigned char *data, int remaining, int which)
{
    TDSInfo_t *tds = uw;

    remaining = MIN(remaining, TDS_MAX_SIZE - tds->pos[which]);
    memcpy(tds->data[which] + tds->pos[which], data, remaining);
    tds->pos[which] += remaining;

    // Lots of info from http://www.freetds.org/tds.html

    if (tds->pos[0] > 598) {
#if 0
        LOG("host:%.*s user:%.*s pass:%.*s process:%.*s app:%.*s server:%.*s lib:%.*s",
                tds->data[0][38], tds->data[0] + 8,
                tds->data[0][69], tds->data[0] + 39,
                tds->data[0][100], tds->data[0] + 70,
                tds->data[0][131], tds->data[0] + 101,
                tds->data[0][178], tds->data[0] + 148,
                tds->data[0][209], tds->data[0] + 179,
                tds->data[0][480], tds->data[0] + 470
                );
#endif
        moloch_field_string_add_lower(userField, session, (const char *)tds->data[0] + 39, tds->data[0][69]);
        moloch_parsers_unregister(session, uw);
    }

    return 0;
}
Esempio n. 4
0
LOCAL int mysql_parser(MolochSession_t *session, void *uw, const unsigned char *data, int len, int which)
{
    Info_t *info = uw;
    if (which != 0) {
        return 0;
    }

    if (info->ssl) {
        moloch_parsers_classify_tcp(session, data, len, which);
        moloch_parsers_unregister(session, info);
        return 0;
    }

    if (len < 35 || data[1] != 0 || data[2] != 0 || data[3] > 2) {
        moloch_parsers_unregister(session, info);
        return 0;
    }

    unsigned char *ptr = (unsigned char*)data + 36;
    unsigned char *end = (unsigned char*)data + len;

    while (ptr < end) {
        if (*ptr == 0)
            break;
        if (!isprint(*ptr)) {
            moloch_parsers_unregister(session, info);
            return 0;
        }
        ptr++;
    }

    moloch_session_add_protocol(session, "mysql");
    moloch_field_string_add(versionField, session, info->version, info->versionLen, FALSE);
    info->version = 0;

    if (ptr > data + 36) {
        moloch_field_string_add_lower(userField, session, (char*)data+36, ptr - (data + 36));
    }

    if (data[5] & 0x08) { //CLIENT_SSL
        info->ssl = 1;
    } else {
        moloch_parsers_unregister(session, info);
    }
    return 0;
}
Esempio n. 5
0
File: tls.c Progetto: ariosx/moloch
int tls_parser(MolochSession_t *session, void *uw, const unsigned char *data, int remaining, int which)
{
    TLSInfo_t            *tls          = uw;

    // If not the server half ignore
    if (which != tls->which)
        return 0;

    // Copy the data we have
    memcpy(tls->buf + tls->len, data, MIN(remaining, (int)sizeof(tls->buf)-tls->len));
    tls->len += MIN(remaining, (int)sizeof(tls->buf)-tls->len);

    // Make sure we have header
    if (tls->len < 5)
        return 0;

    // Not handshake protocol, stop looking
    if (tls->buf[0] != 0x16) {
        tls->len = 0;
        moloch_parsers_unregister(session, uw);
        return 0;
    }

    // Need the whole record
    int need = ((tls->buf[3] << 8) | tls->buf[4]) + 5;
    if (need > tls->len)
        return 0;

    if (tls_process_server_handshake_record(session, tls->buf + 5, need - 5)) {
        tls->len = 0;
        moloch_parsers_unregister(session, uw);
        return 0;
    }
    tls->len -= need;

    // Still more data to process
    if (tls->len) {
        memmove(tls->buf, tls->buf+need, tls->len);
        return 0;
    }

    return 0;
}
Esempio n. 6
0
int dns_tcp_parser(MolochSession_t *session, void *uw, const unsigned char *data, int len, int which)
{
    DNSInfo_t *info = uw;
    while (len >= 2) {

        // First packet of request
        if (info->len[which] == 0) {
            int dnslength = ((data[0]&0xff) << 8) | (data[1] & 0xff);

            if (dnslength < 18) {
                moloch_parsers_unregister(session, uw);
                return 0;
            }

            if (info->size[which] == 0) {
                info->size[which] = MAX(1024,dnslength);
                info->data[which] = malloc(info->size[which]);
            } else if (info->size[which] < dnslength) {
                free(info->data[which]);
                info->data[which] = malloc(dnslength);
                info->size[which] = dnslength;
            }

            // Have all the data in this first packet, just parse it
            if (dnslength <= len-2) {
                dns_parser(session, data+2, dnslength);
                data += 2 + dnslength;
                len -= 2 + dnslength;
            } else {
                memcpy(info->data[which], data+2, len-2);
                info->len[which] = dnslength;
                info->pos[which] = len-2;
                return 0;
            }
        } else {
            int rem = info->len[which] - info->pos[which];
            if (rem <= len) {
                memcpy(info->data[which] + info->pos[which], data, rem);
                len -= rem;
                data += rem;
                dns_parser(session, info->data[which], info->len[which]);
                info->len[which] = 0;
            } else {
                memcpy(info->data[which] + info->pos[which], data, len);
                info->pos[which] += len;
                return 0;
            }
        }
    }
    return 0;
}
Esempio n. 7
0
int socks4_parser(MolochSession_t *session, void *uw, const unsigned char *data, int remaining)
{
    SocksInfo_t            *socks          = uw;

    switch(socks->state4) {
    case SOCKS4_STATE_REPLY:
        if (session->which == socks->which)
            return 0;
        if (remaining >= 8 && data[0] == 0 && data[1] >= 0x5a && data[1] <= 0x5d) {
            if (socks->ip)
                moloch_field_int_add(ipField, session, socks->ip);
            moloch_field_int_add(portField, session, socks->port);
            moloch_nids_add_tag(session, "protocol:socks");
            moloch_nids_add_protocol(session, "socks");

            if (socks->user) {
                if (!moloch_field_string_add(userField, session, socks->user, socks->userlen, FALSE)) {
                    g_free(socks->user);
                }
                socks->user = 0;
            }
            if (socks->host) {
                if (!moloch_field_string_add(hostField, session, socks->host, socks->hostlen, FALSE)) {
                    g_free(socks->host);
                }
                socks->host = 0;
            }
            moloch_parsers_classify_tcp(session, data+8, remaining-8);
            socks->state4 = SOCKS4_STATE_DATA;
            return 8;
        }
        break;
    case SOCKS4_STATE_DATA:
        if (session->which != socks->which)
            return 0;
        moloch_parsers_classify_tcp(session, data, remaining);
        moloch_parsers_unregister(session, uw);
        break;
    }

    return 0;
}
Esempio n. 8
0
int molua_parsers_cb(MolochSession_t *session, void *uw, const unsigned char *data, int remaining, int which)
{
    lua_State *L = Ls[session->thread];
    lua_rawgeti(L, LUA_REGISTRYINDEX, (long)uw);
    molua_pushMolochSession(L, session);
    lua_pushlstring(L, (char *)data, remaining);
    lua_pushnumber(L, which);

    if (lua_pcall(L, 3, 1, 0) != 0) {
       LOG("error running parser function %s", lua_tostring(L, -1));
       exit(0);
    }

    int num = lua_tointeger(L, -1);
    if (num == -1)
        moloch_parsers_unregister(session, uw);
    lua_pop(L, 1);

    return 0;
}
Esempio n. 9
0
// SSH Parsing currently assumes the parts we want from a SSH Packet will be
// in a single TCP packet.  Kind of sucks.
int ssh_parser(MolochSession_t *session, void *uw, const unsigned char *data, int remaining, int which)
{
    SSHInfo_t *ssh = uw;

    if (memcmp("SSH", data, 3) == 0) {
        unsigned char *n = memchr(data, 0x0a, remaining);
        if (n && *(n-1) == 0x0d)
            n--;

        if (n) {
            int len = (n - data);

            char *str = g_ascii_strdown((char *)data, len);

            if (!moloch_field_string_add(verField, session, str, len, FALSE)) {
                g_free(str);
            }
        }
        return 0;
    }

    if (which != 1)
        return 0;

    BSB bsb;
    BSB_INIT(bsb, data, remaining);

    while (BSB_REMAINING(bsb) > 6) {
        uint32_t loopRemaining = BSB_REMAINING(bsb);

        // If 0 looking for a ssh packet, otherwise in the middle of ssh packet
        if (ssh->sshLen == 0) {
            BSB_IMPORT_u32(bsb, ssh->sshLen);

            // Can't have a ssh packet > 35000 bytes.
            if (ssh->sshLen >= 35000) {
                moloch_parsers_unregister(session, uw);
                return 0;
            }
            ssh->sshLen += 4;

            uint8_t    sshCode = 0;
            BSB_IMPORT_skip(bsb, 1); // padding length
            BSB_IMPORT_u08(bsb, sshCode);

            if (sshCode == 33) {
                moloch_parsers_unregister(session, uw);

                uint32_t keyLen = 0;
                BSB_IMPORT_u32(bsb, keyLen);

                if (!BSB_IS_ERROR(bsb) && BSB_REMAINING(bsb) >= keyLen) {
                    char *str = g_base64_encode(BSB_WORK_PTR(bsb), keyLen);
                    if (!moloch_field_string_add(keyField, session, str, (keyLen/3+1)*4, FALSE)) {
                        g_free(str);
                    }
                }
                break;
            }
        }

        if (loopRemaining > ssh->sshLen) {
            // Processed all, looking for another packet
            BSB_IMPORT_skip(bsb, loopRemaining);
            ssh->sshLen = 0;
            continue;
        } else {
            // Waiting on more data then in this callback
            ssh->sshLen -= loopRemaining;
            break;
        }
    }
    return 0;
}
Esempio n. 10
0
int socks5_parser(MolochSession_t *session, void *uw, const unsigned char *data, int remaining, int which)
{
    SocksInfo_t            *socks          = uw;
    int                     consumed;

    //LOG("%d %d %d", which, socks->which, socks->state5[which]);
    //moloch_print_hex_string(data, remaining);

    switch(socks->state5[which]) {
    case SOCKS5_STATE_VER_REQUEST:
        if (data[2] == 0) {
            socks->state5[which] = SOCKS5_STATE_CONN_REQUEST;
        } else {
            socks->state5[which] = SOCKS5_STATE_USER_REQUEST;
        }
        socks->state5[(which+1)%2] = SOCKS5_STATE_VER_REPLY;
        break;
    case SOCKS5_STATE_VER_REPLY:
        if (remaining != 2 || data[0] != 5 || data[1] > 2) {
            moloch_parsers_unregister(session, uw);
            return 0;
        }

        moloch_nids_add_protocol(session, "socks");

        if (socks->state5[socks->which] == SOCKS5_STATE_CONN_DATA) {
            // Other side of connection already in data state
            socks->state5[which] = SOCKS5_STATE_CONN_REPLY;
        } else if (data[1] == 0) {
            socks->state5[socks->which] = SOCKS5_STATE_CONN_REQUEST;
            socks->state5[which] = SOCKS5_STATE_CONN_REPLY;
        } else if (data[1] == 2) {
            socks->state5[socks->which] = SOCKS5_STATE_USER_REQUEST;
            socks->state5[which] = SOCKS5_STATE_USER_REPLY;
        } else {
            // We don't handle other auth methods
            moloch_parsers_unregister(session, uw);
        }


        return 2;
    case SOCKS5_STATE_USER_REQUEST:
        if ((2 + data[1] > (int)remaining) || (2 + data[1] + 1 + data[data[1]+2]  > (int)remaining)) {
            moloch_parsers_unregister(session, uw);
            return 0;
        }

        moloch_field_string_add(userField, session, (char *)data + 2, data[1], TRUE);
        moloch_nids_add_tag(session, "socks:password");
        socks->state5[which] = SOCKS5_STATE_CONN_REQUEST;
        return data[1] + 1 + data[data[1]+2];
    case SOCKS5_STATE_USER_REPLY:
        socks->state5[which] = SOCKS5_STATE_CONN_REPLY;
        return 2;
    case SOCKS5_STATE_CONN_REQUEST:
        if (remaining < 6 || data[0] != 5 || data[1] != 1 || data[2] != 0) {
            moloch_parsers_unregister(session, uw);
            return 0;
        }

        socks->state5[which] = SOCKS5_STATE_CONN_DATA;
        if (data[3] == 1) { // IPV4
            socks->port = (data[8]&0xff) << 8 | (data[9]&0xff);
            memcpy(&socks->ip, data+4, 4);
            moloch_field_int_add(ipField, session, socks->ip);
            moloch_field_int_add(portField, session, socks->port);
            consumed = 4 + 4 + 2;
        } else if (data[3] == 3) { // Domain Name
            socks->port = (data[5+data[4]]&0xff) << 8 | (data[6+data[4]]&0xff);
            char *lower = g_ascii_strdown((char*)data+5, data[4]);
            if (!moloch_field_string_add(hostField, session, lower, data[4], FALSE)) {
                g_free(lower);
            }
            moloch_field_int_add(portField, session, socks->port);
            consumed = 4 + 1 + data[4] + 2;
        } else if (data[3] == 4) { // IPV6
            consumed = 4 + 16 + 2;
        } else {
            break;
        }

        moloch_parsers_classify_tcp(session, data+consumed, remaining-consumed, which);
        return consumed;
    case SOCKS5_STATE_CONN_REPLY: {
        if (remaining < 6) {
            moloch_parsers_unregister(session, uw);
            return 0;
        }

        socks->state5[which] = SOCKS5_STATE_CONN_DATA;
        if (data[3] == 1) { // IPV4
            consumed = 4 + 4 + 2;
        } else if (data[3] == 3) { // Domain Name
            consumed = 4 + 1 + data[4] + 2;
        } else if (data[3] == 4) { // IPV6
            consumed = 4 + 16 + 2;
        } else {
            break;
        }
        moloch_parsers_classify_tcp(session, data+consumed, remaining-consumed, which);
        return consumed;
    }
    case SOCKS5_STATE_CONN_DATA:
        moloch_parsers_classify_tcp(session, data, remaining, which);
        moloch_parsers_unregister(session, uw);
        return 0;
    default:
        moloch_parsers_unregister(session, uw);
    }

    return 0;
}
Esempio n. 11
0
File: quic.c Progetto: paulpc/moloch
LOCAL int quic_udp_parser(MolochSession_t *session, void *UNUSED(uw), const unsigned char *data, int len, int UNUSED(which))
{
    int version = -1;
    int offset = 1;

    // PUBLIC_FLAG_RESET
    if (data[0] & 0x02) {
        return 0;
    }

    // CID
    if (data[0] & 0x08) {
        offset += 8;
    }

    // Get version
    if (data[0] & 0x01 && data[offset] == 'Q') {
        version = (data[offset+1] - '0') * 100 +
                  (data[offset+2] - '0') * 10 +
                  (data[offset+3] - '0');
        offset += 4;
    }

    // Unsupported version
    if (version < 24) {
        moloch_parsers_unregister(session, uw);
        return 0;
    }

    // Diversification only is from server to client, so we can ignore

    // Packet number size
    if ((data[0] & 0x30) == 0) {
        offset++;
    } else {
        offset += ((data[0] & 0x30) >> 4) * 2;
    }

    // Hash
    offset += 12;

    // Private Flags
    if (version < 34)
        offset++;

    if (offset > len)
        return 0;

    BSB bsb;
    BSB_INIT(bsb, data+offset, len-offset);

    while (!BSB_IS_ERROR(bsb) && BSB_REMAINING(bsb)) {
        uint8_t type = 0;
        BSB_LIMPORT_u08(bsb, type);

        //1fdooossB
        if ((type & 0x80) == 0) {
            return 0;
        }

        int offsetLen = 0;
        if (type & 0x1C) {
            offsetLen = ((type & 0x1C) >> 2) + 1;
        }

        int streamLen = (type & 0x03) + 1;

        BSB_LIMPORT_skip(bsb, streamLen + offsetLen);

        int dataLen = BSB_REMAINING(bsb);
        if (type & 0x20) {
            BSB_LIMPORT_u16(bsb, dataLen);
        }

        if (BSB_IS_ERROR(bsb))
            return 0;

        BSB dbsb;
        BSB_INIT(dbsb, BSB_WORK_PTR(bsb), MIN(dataLen, BSB_REMAINING(bsb)));
        BSB_IMPORT_skip(bsb, dataLen);

        quic_chlo_parser(session,dbsb);
        moloch_parsers_unregister(session, uw);
        return 0;
    }