int load_bmp (IMAGEDATA *im, const char *filename) { FILE *fp; uint16 x; int ret; uint8 *data = NULL; uint8 *ptr = NULL; int size = 0; struct stat st; if (stat (filename, &st) == -1) { I_Perror ("Error statting file %s", filename); return (-1); } size = st.st_size; data = ptr = (uint8 *) malloc (size * sizeof(uint8)); if ((fp = fopen (filename, "r")) == NULL) { free(ptr); I_Perror ("Error openning file %s", filename); return (-1); } if (fread(data, sizeof(uint8), size, fp) < size) { free(ptr); I_Perror ("Error reading file %s", filename); return (-1); } fclose (fp); x = read_little_16 (&data); switch (x) { case BMP_TYPE_V1: I_Message ("Type 1 BMP\n"); break; case BMP_TYPE_V3: // I_Message ("Type 3 BMP\n"); ret = load_bmp_v3 (im, data); break; default: I_Message ("UnknownBMP\n"); } free (ptr); return ret; }
// move cursor to the beginning of a device independent bitmap (DIB) DEBUG_SO(printf("offBmi=0x%08x\n", offBmi);) cursor_normal += offBmi - 4; if(cursor_normal + 12 > end_of_payload) return RULE_NOMATCH; // match size of BITMAPCOREHEADER to determine if it's the proper structure bcSize = read_little_32(cursor_normal); cursor_normal += 4; DEBUG_SO(printf("bcSize=0x%08x\n", bcSize);) if (bcSize == 12) // checks BITMAPCOREHEADER { bcWidth = read_little_16(cursor_normal); cursor_normal += 2; bcHeight = read_little_16(cursor_normal); cursor_normal += 2; bcPlanes = read_little_16(cursor_normal); cursor_normal += 2; bcBitCount = read_little_16(cursor_normal); cursor_normal += 2; DEBUG_SO(printf("bcWidth=%xh bcHeight=%xh bcPlanes=%xh bcBitCount=%xh\n", bcWidth,bcHeight,bcPlanes,bcBitCount);) // 16-bit * 16-bit can't be more than 32-bit Value = (bcWidth * bcPlanes) & 0xFFFFFFFF;
int load_bmp_v3 (IMAGEDATA *im, uint8 *data) { uint8 byte; uint16 word; uint32 dword, data_offset; uint32 compression, size; uint32 scan_len, data_len; int x, y; /* go through header */ dword = read_little_32 (&data); dword = read_little_32 (&data); data_offset = read_little_32 (&data); /* load info struct */ /* header size */ dword = read_little_32 (&data); if (dword != 40) { I_Error ("load_bmp(): Unexpected header size, expected 40 got %d", word); return (-1); } dword = read_little_32 (&data); im->width = dword; dword = read_little_32 (&data); im->height = dword; /* image planes, always 1 */ word = read_little_16 (&data); /* bits per pixel */ word = read_little_16 (&data); im->colordepth = word; /* compression method */ dword = read_little_32 (&data); compression = dword; dword = read_little_32 (&data); size = dword; if (!size) { I_Message ("-W- Uh oh, image size is 0, guessing\n"); size = im->height * im->width * im->colordepth / 8; } // else // I_Message ("Size is %d\n", size); /* horz resolution */ dword = read_little_32 (&data); /* vert resolution */ dword = read_little_32 (&data); /* colors */ dword = read_little_32 (&data); im->numcolors = dword; /* significant colors */ dword = read_little_32 (&data); /* Palette on 1, 4 or 8 bit displays */ if (im->colordepth != 24) { if (im->numcolors == 0) { /* Hmm, if numcolors is 0, guess using the start of data */ im->numcolors = (data_offset - 54) / 4; } im->palette = (RGBQUAD *) malloc (im->numcolors * sizeof (RGBQUAD)); for (x = 0; x < im->numcolors; x++) { dword = read_little_32 (&data); im->palette[x].red = (dword >> 16) & 0x0ff; im->palette[x].green = (dword >> 8) & 0x0ff; im->palette[x].blue = (dword >> 0) & 0x0ff; } } else
/* detection functions */ int rule16531eval(void *p) { const uint8_t *cursor_normal = 0, *beg_of_payload, *end_of_payload; SFSnortPacket *sp = (SFSnortPacket *) p; if(sp == NULL) return RULE_NOMATCH; if(sp->payload == NULL) return RULE_NOMATCH; // flow:established, to_client; if (checkFlow(p, rule16531options[0]->option_u.flowFlags) > 0 ) { if(getBuffer(sp, CONTENT_BUF_NORMALIZED, &beg_of_payload, &end_of_payload) <= 0) return RULE_NOMATCH; cursor_normal = beg_of_payload; //The while loop is for reassembled packets that have multiple SMB messages // content:"|FF|SMB2", payload raw, offset 4, depth 5, fast_pattern; while (contentMatch(p, rule16531options[1]->option_u.content, &cursor_normal) > 0) { uint32_t nb_len; uint16_t wc; uint16_t dataoffset; uint16_t datacount; uint16_t bcc; //Should be a NetBIOS header if ((cursor_normal - beg_of_payload) < 9) return RULE_NOMATCH; nb_len = *(cursor_normal-6); nb_len |= *(cursor_normal-7) << 8; nb_len |= *(cursor_normal-8) << 16; //Make sure enough data is there to check all necessary fields if (cursor_normal+44 > end_of_payload) return RULE_NOMATCH; //Extract Word Count wc = *(cursor_normal+27) << 1; // Someone's being clever multiplying by 2 // XXX Have seen this with a word count of 0 - means no datacount or dataoffset // cursor_normal+44 should normally catch this but if there is another request // because of a reassembled packet, we'll get here. // This is just to avoid false positives if (wc == 0) { cursor_normal += 30; continue; } //Extract Data Count and Data Offset datacount = read_little_16(cursor_normal+40); dataoffset = read_little_16(cursor_normal+42); if (dataoffset == 0) return RULE_NOMATCH; //Check to see if there is enough space for the word count field //plus word count * 2 bytes, the two-byte bcc field. if ((cursor_normal + 30 + wc) > end_of_payload) return RULE_NOMATCH; //data offset should be always less than the NetBIOS length //If not, dataoffset is jacked, so alert if (nb_len < dataoffset) return RULE_MATCH; //Data is the last field in the payload section of the SMB trans response //It should be equal to NetBIOS length - dataoffset if ((nb_len - dataoffset) > datacount) return RULE_MATCH; cursor_normal += 28 + wc; //Extract bcc bcc = read_little_16_inc(cursor_normal); //Jump to the end of the data cursor_normal += bcc; } } return RULE_NOMATCH; }