Changeset 1560
- Timestamp:
- 02/19/08 22:19:41 (6 months ago)
- Files:
-
- nebula/trunk/src/Makefile.am (modified) (1 diff)
- nebula/trunk/src/Makefile.in (deleted)
- nebula/trunk/src/cluster.h (modified) (1 diff)
- nebula/trunk/src/nebula.c (modified) (2 diffs)
- nebula/trunk/src/nebula.h (modified) (2 diffs)
- nebula/trunk/src/session.c (modified) (10 diffs)
- nebula/trunk/src/session.h (modified) (2 diffs)
- nebula/trunk/src/sha512.c (added)
- nebula/trunk/src/sha512.h (added)
- nebula/trunk/src/sig.c (modified) (8 diffs)
- nebula/trunk/src/sig.h (modified) (2 diffs)
- nebula/trunk/src/util.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
nebula/trunk/src/Makefile.am
r1559 r1560 6 6 nebula_SOURCES = signals.c signals.h \ 7 7 md5.c md5.h \ 8 sha512.c sha512.h \ 8 9 spamsum.c spamsum.h \ 9 10 util.c util.h \ nebula/trunk/src/cluster.h
r1558 r1560 36 36 * for ngram vectors */ 37 37 typedef struct cluster { 38 u_int16_t cnt; 39 void *parent; 40 struct cluster *prev; 41 struct cluster *next; 42 queue *hq; 43 38 u_int32_t cnt; 39 u_int32_t sig_id; 40 u_int32_t sig_rev; 41 void *parent; 42 struct cluster *prev; 43 struct cluster *next; 44 queue *hq; 44 45 } cluster; 45 46 nebula/trunk/src/nebula.c
r1558 r1560 104 104 memset(&md5sum_trie, 0, sizeof(trie_node)); 105 105 memset(&spamsum_trie, 0, sizeof(trie_node)); 106 107 pthread_rwlock_init(&md5sum_trie_lock, NULL); 108 pthread_rwlock_init(&spamsum_trie_lock, NULL); 109 pthread_rwlock_init(&sidlock, NULL); 106 memset(&sighash_trie, 0, sizeof(trie_node)); 107 108 if (pthread_rwlock_init(&md5sum_trie_lock, NULL) || 109 pthread_rwlock_init(&spamsum_trie_lock, NULL) || 110 pthread_rwlock_init(&sighash_trie_lock, NULL) || 111 pthread_rwlock_init(&sidlock, NULL)) { 112 fprintf(stderr, "Error - Unable to initialize queue mutex: %m.\n"); 113 exit(EXIT_FAILURE); 114 } 110 115 111 116 printf("\n Nebula %s Copyright (C) 2007-2008 Tillmann Werner <tillmann.werner@gmx.de>\n\n", VERSION); … … 223 228 // create submission copy so that we can reset the session 224 229 memcpy(&tmp_submission, &s[i], sizeof(submission)); 225 s[i].secret = NULL;226 230 s[i].attack = NULL; 227 231 s[i].cattack = NULL; nebula/trunk/src/nebula.h
r1559 r1560 36 36 u_char verbose; 37 37 char *secret; 38 trie_node spamsum_trie, md5sum_trie ;38 trie_node spamsum_trie, md5sum_trie, sighash_trie; 39 39 40 40 ssize_t clusterq_max, clusterhashq_max, outlierq_max; … … 47 47 pthread_rwlock_t md5sum_trie_lock; 48 48 pthread_rwlock_t spamsum_trie_lock; 49 pthread_rwlock_t sighash_trie_lock; 49 50 50 51 #endif nebula/trunk/src/session.c
r1558 r1560 30 30 #include "nebula.h" 31 31 #include "session.h" 32 #include "sha512.h" 32 33 #include "util.h" 33 34 34 35 35 36 void session_reset(submission *s, struct pollfd *pfd) { 36 free(s->secret);37 37 free(s->cattack); 38 38 free(s->attack); … … 64 64 65 65 int session_handle_data(struct pollfd *pfd, submission *s) { 66 int rv; 67 char *md5sum; 66 int rv; 67 char *md5sum; 68 char *sha512sum; 69 char *secret_randno; 70 trie_node *t; 68 71 69 72 if (!pfd || !s) { … … 74 77 switch (s->state) { 75 78 case NEW: 76 // read secret length 77 if ((rv = session_read_data(pfd->fd, s, (u_char *) &(s->secret_len), 1)) == -1) { 78 session_reset(s, pfd); 79 return(-1); 80 } else if (rv == 1) { 81 s->bytes_read = 0; 82 s->state = SECRET_LEN_READ; 83 if (verbose > 1) printf(" secret length: %u\n", s->secret_len); 84 } 85 break; 86 case SECRET_LEN_READ: 87 // read secret 88 if ((s->secret = calloc(sizeof(char), s->secret_len + 1)) == NULL) { 89 fprintf(stderr, "Error - Unable to allocate memory: %s.\n", strerror(errno)); 90 exit(EXIT_FAILURE); 91 } 92 if ((rv = session_read_data(pfd->fd, s, (u_char *) s->secret, s->secret_len)) == -1) { 93 session_reset(s, pfd); 94 return(-1); 95 } else if (rv == s->secret_len) { 96 if (verbose > 1) printf(" secret: %s\n", s->secret); 97 if (strlen(secret) == strlen(s->secret) && !strncmp(secret, s->secret, strlen(secret))) { 98 s->bytes_read = 0; 79 // read random number 80 s->bytes_read = 0; 81 if ((rv = session_read_data(pfd->fd, s, (u_char *) &(s->rand_no), 4)) == -1) { 82 session_reset(s, pfd); 83 return(-1); 84 } else if (rv == 4) { 85 s->state = RANDNO_READ; 86 if (verbose > 1) printf(" random number: %u\n", s->rand_no); 87 } 88 break; 89 case RANDNO_READ: 90 // read secret hash 91 s->bytes_read = 0; 92 if ((rv = session_read_data(pfd->fd, s, (u_char *) s->secret_hash, 128)) == -1) { 93 session_reset(s, pfd); 94 return(-1); 95 } else if (rv == 128) { 96 s->state = UNAUTHENTICATED; 97 98 if ((secret_randno = malloc(strlen(secret) + 4)) == NULL) { 99 fprintf(stderr, "Error - Unable to allocate memory: %s.\n", strerror(errno)); 100 return(-1); 101 } 102 memcpy(secret_randno, secret, strlen(secret)); 103 memcpy(secret_randno+strlen(secret), &s->rand_no, 4); 104 105 if ((sha512sum = mem_sha512sum((u_char *) secret_randno, strlen(secret) + 4)) == NULL) { 106 fprintf(stderr, "Error - Unable to hash secret.\n"); 107 return(-1); 108 } 109 free(secret_randno); 110 111 if (!strncmp(sha512sum, s->secret_hash, 128)) { 99 112 s->state = AUTHENTICATED; 100 if (verbose > 1) printf(" session authenticated.\n"); 101 } else { 102 if (verbose > 1) printf(" secret mismatch.\n"); 113 if (verbose > 1) printf(" valid secret hash read, session authenticated.\n"); 114 } 115 116 free(sha512sum); 117 118 if (s->state != AUTHENTICATED) { 119 if (verbose > 1) printf(" secret mismatch, dropping session.\n"); 103 120 session_reset(s, pfd); 104 121 } … … 111 128 exit(EXIT_FAILURE); 112 129 } 130 s->bytes_read = 0; 113 131 if ((rv = session_read_data(pfd->fd, s, (u_char *) s->md5sum, 32)) == -1) { 114 132 session_reset(s, pfd); … … 116 134 } else if (rv == 32) { 117 135 s->md5sum[32] = 0; 118 s->bytes_read = 0; 119 120 if (write(pfd->fd, "UNKNOWN\n", 8) == -1) { 121 fprintf(stderr, "Error - Unable to send data request: %s.\n", strerror(errno)); 122 session_reset(s, pfd); 123 return(-1); 124 } 125 136 if (verbose > 1) printf(" attack md5sum: %s\n", s->md5sum); 137 138 pthread_rwlock_rdlock(&md5sum_trie_lock); 139 t = trie_find_memstr(&md5sum_trie, (u_char *) s->md5sum, strlen(s->md5sum)); 140 pthread_rwlock_unlock(&md5sum_trie_lock); 141 142 if (t != NULL) { 143 // md5sum is already in trie 144 if (write(pfd->fd, "KNOWN\n", 6) == -1) { 145 fprintf(stderr, "Error - Unable to send data request: %s.\n", strerror(errno)); 146 session_reset(s, pfd); 147 return(-1); 148 } 149 if (verbose > 1) printf(" known attack, rejecting submission.\n"); 150 session_reset(s, pfd); 151 return(0); 152 } else { 153 // unknown attack hash, send request 154 if (write(pfd->fd, "UNKNOWN\n", 8) == -1) { 155 fprintf(stderr, "Error - Unable to send data request: %s.\n", strerror(errno)); 156 session_reset(s, pfd); 157 return(-1); 158 } 159 } 160 161 if (verbose > 1) printf(" unknown attack, submission requested.\n"); 126 162 s->state = REQUEST_SENT; 127 if (verbose > 1) printf(" md5sum: %s\n", s->md5sum);128 163 } 129 164 break; 130 165 case REQUEST_SENT: 131 166 // read protocol 167 s->bytes_read = 0; 132 168 if ((rv = session_read_data(pfd->fd, s, (u_char *) &(s->protocol), 1)) == -1) { 133 169 session_reset(s, pfd); 134 170 return(-1); 135 171 } else if (rv == 1) { 136 s->bytes_read = 0;137 172 s->state = PROTOCOL_READ; 138 173 switch (s->protocol) { … … 153 188 case PROTOCOL_READ: 154 189 // read port 190 s->bytes_read = 0; 155 191 if ((rv = session_read_data(pfd->fd, s, (u_char *) &(s->port), 2)) == -1) { 156 192 session_reset(s, pfd); 157 193 return(-1); 158 194 } else if (rv == 2) { 159 s->bytes_read = 0;160 195 s->state = PORT_READ; 161 196 if (verbose > 1) printf(" port: %u\n", s->port); … … 164 199 case PORT_READ: 165 200 // read length of attack data 201 s->bytes_read = 0; 166 202 if ((rv = session_read_data(pfd->fd, s, (u_char *) &(s->attack_len), 4)) == -1) { 167 203 session_reset(s, pfd); 168 204 return(-1); 169 205 } else if (rv == 4) { 170 s->bytes_read = 0;171 206 s->state = ATTACK_LEN_READ; 172 207 if (verbose > 1) printf(" bytes of attacks: %lu\n", s->attack_len); … … 175 210 case ATTACK_LEN_READ: 176 211 // read length of compressed attack data 212 s->bytes_read = 0; 177 213 if ((rv = session_read_data(pfd->fd, s, (u_char *) &(s->cattack_len), 4)) == -1) { 178 214 session_reset(s, pfd); 179 215 return(-1); 180 216 } else if (rv == 4) { 181 s->bytes_read = 0;182 217 s->state = CATTACK_LEN_READ; 183 218 if (verbose > 1) printf(" bytes of compressed attacks: %u\n", s->cattack_len); … … 185 220 break; 186 221 case CATTACK_LEN_READ: 187 188 222 // read compressed attack 189 223 if ((s->cattack = calloc(sizeof(u_char), s->cattack_len)) == NULL) { … … 191 225 exit(EXIT_FAILURE); 192 226 } 227 s->bytes_read = 0; 193 228 if ((rv = session_read_data(pfd->fd, s, s->cattack, s->cattack_len)) == -1) { 194 229 session_reset(s, pfd); nebula/trunk/src/session.h
r1558 r1560 29 29 #include <sys/types.h> 30 30 31 32 31 typedef enum sstate { 33 32 NEW = 0, 34 SECRET_LEN_READ, 33 RANDNO_READ, 34 UNAUTHENTICATED, 35 35 AUTHENTICATED, 36 36 REQUEST_SENT, … … 43 43 44 44 typedef struct submission { 45 sstate state; // session state46 ssize_t bytes_read; // number of bytes read so far47 u_ char secret_len; // length of secret string48 char *secret; // secret string49 u_char protocol; // attack protocol50 u_int16_t port; // attack port51 u_int32_t cattack_len; // length of compressed attack data52 unsigned long attack_len; // length of uncompressed attack data53 u_char *cattack; // compressed attack data54 u_char *attack; // uncompressed attack data55 char *md5sum; // md5 hash of uncompressed attack data45 sstate state; // session state 46 ssize_t bytes_read; // number of bytes read so far 47 u_int32_t rand_no; // random number (hashed together with secret string) 48 char secret_hash[129]; // hashed secret 49 u_char protocol; // attack protocol 50 u_int16_t port; // attack port 51 u_int32_t cattack_len; // length of compressed attack data 52 unsigned long attack_len; // length of uncompressed attack data 53 u_char *cattack; // compressed attack data 54 u_char *attack; // uncompressed attack data 55 char *md5sum; // md5 hash of uncompressed attack data 56 56 } submission; 57 57 nebula/trunk/src/sig.c
r1559 r1560 24 24 #include <string.h> 25 25 26 #include "cluster.h" 26 27 #include "cstr.h" 27 28 #include "nebula.h" 28 29 #include "session.h" 30 #include "sha512.h" 29 31 #include "sig.h" 30 32 #include "stree.h" … … 70 72 71 73 72 void build_sig( stree *t, lcatbl *lca_table, substr_list list, stnode **leaves, ssize_t num_leaves, ssize_t min_len, double min_ent, sigtype stype) {74 void build_sig(cluster *cl, stree *t, lcatbl *lca_table, substr_list list, stnode **leaves, ssize_t num_leaves, ssize_t min_len, double min_ent, sigtype stype) { 73 75 int i, j, printable; 74 76 double ent; 75 u_int32_t start , sid;76 ssize_t leaf, id, l, r;77 u_int32_t start; 78 ssize_t sigdata_len, leaf, id, l, r; 77 79 sseg *seglist; 80 u_char *sigdata; 81 char *sha512sum; 82 trie_node *n; 78 83 79 84 ssize_t num_frags; … … 81 86 82 87 num_frags = 0; 88 sigdata_len = 0; 83 89 seglist = NULL; 90 sigdata = NULL; 84 91 85 92 for (i = 0; i < list.len; i++) { … … 116 123 } 117 124 125 126 // store signature info into for hashing a contiguous memory area 127 for (i=num_frags; i; i--) { 128 // append next signature segment 129 if ((sigdata = realloc(sigdata, sigdata_len + sizeof(sseg) + seglist[i-1].len)) == NULL) { 130 fprintf(stderr, "Error - Unable to allocate memory: %m.\n"); 131 free(sigdata); 132 return; 133 } 134 memcpy(&sigdata[sigdata_len], &seglist[i-1], sizeof(sseg)); 135 sigdata_len += sizeof(sseg); 136 memcpy(&sigdata[sigdata_len], &t->tree_string[seglist[i-1].org_off+1], seglist[i-1].len); 137 sigdata_len += seglist[i-1].len; 138 } 139 140 // hash signature and do a trie lookup 141 sha512sum = mem_sha512sum(sigdata, sigdata_len); 142 printf("[=] signature hash: %s\n", sha512sum); 143 144 pthread_rwlock_rdlock(&sighash_trie_lock); 145 n = trie_find_memstr(&sighash_trie, (u_char *) sha512sum, 128); 146 pthread_rwlock_unlock(&sighash_trie_lock); 147 148 if (n != NULL) { 149 // signature was generated earlier so skip it 150 printf("[=] signature was already published.\n"); 151 free(sha512sum); 152 return; 153 } else { 154 // insert signature hash into trie 155 pthread_rwlock_wrlock(&sighash_trie_lock); 156 n = trie_memins(&sighash_trie, (u_char *) sha512sum, 128, NULL); 157 n->data = cl; 158 pthread_rwlock_unlock(&sighash_trie_lock); 159 } 160 free(sha512sum); 161 162 118 163 switch (stype) { 119 164 case SIG_RAW: 120 165 // print raw signature 166 printf("\n---- Signature type: raw ------------------------------------------------------------------------------\n"); 121 167 for (i=num_frags; i; i--) { 122 168 printf("#\033[1;32m[%lu]\033[1;31m[\033[1;0m", (long unsigned int) seglist[i-1].min_off); … … 125 171 printf("\033[1;31m]\033[1;32m[%lu]\033[1;0m ", (long unsigned int) seglist[i-1].max_off+seglist[i-1].len); 126 172 } 127 printf(" \n");173 printf("-----------------------------------------------------------------------------------------------------------\n\n"); 128 174 break; 129 175 case SIG_SNORT: 130 // increase global sid 131 pthread_rwlock_wrlock(&sidlock); 132 sid = ++global_sid; 133 pthread_rwlock_unlock(&sidlock); 176 if (!cl->sig_id) { 177 // increase global sid 178 pthread_rwlock_wrlock(&sidlock); 179 cl->sig_id = ++global_sid; 180 pthread_rwlock_unlock(&sidlock); 181 } 182 183 // increase revision number 184 cl->sig_rev++; 134 185 135 186 // print snort signature 136 187 printf("\n---- Signature type: snort ----------------------------------------------------------------------------\n"); 137 printf("alert tcp any any -> any any (msg: \"nebula rule %u \";", sid);188 printf("alert tcp any any -> any any (msg: \"nebula rule %u rev. %u\";", cl->sig_id, cl->sig_rev); 138 189 if (num_frags) { 139 190 printf(" \\\n content: \""); … … 209 260 (long unsigned int) seglist[i-1].max_off + seglist[i-1].len - seglist[i].min_off); 210 261 } 211 printf(" \\\n sid: %u; )\n", sid);212 } 213 printf("-------------------------------------------------------------------------------------------------- \n\n");262 printf(" \\\n sid: %u; rev: %u;)\n", cl->sig_id, cl->sig_rev); 263 } 264 printf("-----------------------------------------------------------------------------------------------------------\n\n"); 214 265 break; 215 266 default: … … 291 342 292 343 // print concatenated string 293 if (verbose ) {344 if (verbose > 1) { 294 345 printf("Concatenated string (%u) is '", strllen); 295 346 for (i = 0; i < strllen; i++) { … … 348 399 // list_substrings(gst, cstr_list.elem[i].n, cstr_list.elem[i].len); 349 400 350 build_sig( gst, lca_table, cstr_list, leaves, num_leaves, min_sstr_len, min_sstr_ent, SIG_SNORT);401 build_sig(cl, gst, lca_table, cstr_list, leaves, num_leaves, min_sstr_len, min_sstr_ent, SIG_SNORT); 351 402 352 403 nebula/trunk/src/sig.h
r1558 r1560 39 39 struct { 40 40 sigtype type; 41 cluster cl;42 41 void *metainfo; 43 42 time_t create_time; … … 53 52 54 53 55 void build_sig( stree *t, lcatbl *lca_table, substr_list list, stnode **leaves, ssize_t num_leaves, ssize_t min_len, double min_ent, sigtype stype);54 void build_sig(cluster *cl, stree *t, lcatbl *lca_table, substr_list list, stnode **leaves, ssize_t num_leaves, ssize_t min_len, double min_ent, sigtype stype); 56 55 void *pt_siggen(void *cl); 57 56 nebula/trunk/src/util.c
r1558 r1560 155 155 pthread_rwlock_unlock(&spamsum_trie_lock); 156 156 157 pthread_rwlock_wrlock(&sighash_trie_lock); 158 trie_delete(sighash_trie.childlist, sighash_trie.childlist_len, NULL); 159 pthread_rwlock_unlock(&sighash_trie_lock); 160 157 161 pthread_rwlock_destroy(&md5sum_trie_lock); 158 162 pthread_rwlock_destroy(&spamsum_trie_lock); 163 pthread_rwlock_destroy(&sighash_trie_lock); 159 164 160 165 return;
