DLL_FOREACH_REMOVABLE(td_, tcpData, ftd, next) { const int which = ftd->packet->direction; const uint32_t tcpSeq = session->tcpSeq[which]; if (tcpSeq >= ftd->seq && tcpSeq < (ftd->seq + ftd->len)) { const int offset = tcpSeq - ftd->seq; const uint8_t *data = ftd->packet->pkt + ftd->dataOffset + offset; const int len = ftd->len - offset; if (session->firstBytesLen[which] < 8) { int copy = MIN(8 - session->firstBytesLen[which], len); memcpy(session->firstBytes[which] + session->firstBytesLen[which], data, copy); session->firstBytesLen[which] += copy; } if (session->totalDatabytes[which] == session->consumed[which]) { moloch_parsers_classify_tcp(session, data, len, which); } moloch_packet_process_data(session, data, len, which); session->tcpSeq[which] += len; session->databytes[which] += len; session->totalDatabytes[which] += len; if (config.yara) { moloch_yara_execute(session, data, len, 0); } DLL_REMOVE(td_, tcpData, ftd); moloch_packet_free(ftd->packet); MOLOCH_TYPE_FREE(MolochTcpData_t, ftd); } else { return; } }
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; }
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; }
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; }