Beispiel #1
0
void tcpdemux::post_process(tcpip *tcp)
{
    std::stringstream xmladd;		// for this <fileobject>
    if(opt.post_processing && tcp->file_created && tcp->last_byte>0){
        /** 
         * After the flow is finished, if more than a byte was
         * written, then put it in an SBUF and process it.  if we are
         * doing post-processing.  This is called from tcpip::~tcpip()
         * in tcpip.cpp.
         */

        /* Open the fd if it is not already open */
        tcp->open_file();
        if(tcp->fd>=0){
            sbuf_t *sbuf = sbuf_t::map_file(tcp->flow_pathname,pos0_t(tcp->flow_pathname),tcp->fd);
            if(sbuf){
                be13::plugin::process_sbuf(scanner_params(scanner_params::PHASE_SCAN,*sbuf,*(fs),&xmladd));
                delete sbuf;
                sbuf = 0;
            }
        }
    }
    tcp->close_file();
    if(xreport) tcp->dump_xml(xreport,xmladd.str());
    /**
     * Before we delete the tcp structure, save information about the saved flow
     */
    save_flow(tcp);
    delete tcp;
}
Beispiel #2
0
static void process_gzip(class tcpdemux &demux,
                         std::stringstream &ss,
                         const std::string &fname,const unsigned char *base,size_t len)
{
    if((len>4) && (base[0]==0x1f) && (base[1]==0x8b) && (base[2]==0x08) && (base[3]==0x00)) {
        size_t uncompr_size = len * 16;
        unsigned char *decompress_buf = (unsigned char *)malloc(uncompr_size);
        if(decompress_buf==0) return;	// too big?

        z_stream zs;
        memset(&zs,0,sizeof(zs));
        zs.next_in = (Bytef *)base; // note that next_in should be typedef const but is not
        zs.avail_in = len;
        zs.next_out = decompress_buf;
        zs.avail_out = uncompr_size;

        int r = inflateInit2(&zs,16+MAX_WBITS);
        if(r==0) {
            r = inflate(&zs,Z_SYNC_FLUSH);
            /* Ignore the error return; process data if we got anything */
            if(zs.total_out>0) {
                demux.write_to_file(ss,fname,sbuf_t(pos0_t(),decompress_buf,zs.total_out,zs.total_out,false));
            }
            inflateEnd(&zs);
        }
        free(decompress_buf);
    }
}
Beispiel #3
0
int tcpdemux::process_ip4(const be13::packet_info &pi)
{
    /* make sure that the packet is at least as long as the min IP header */
    if (pi.ip_datalen < sizeof(struct be13::ip4)) {
	DEBUG(6) ("received truncated IP datagram!");
	return -1;                      // couldn't process
    }

    const struct be13::ip4 *ip_header = (struct be13::ip4 *) pi.ip_data;

    DEBUG(100)("process_ip4. caplen=%d vlan=%d  ip_p=%d",(int)pi.pcap_hdr->caplen,(int)pi.vlan(),(int)ip_header->ip_p);
    if(debug>200){
	sbuf_t sbuf(pos0_t(),(const uint8_t *)pi.ip_data,pi.ip_datalen,pi.ip_datalen,false);
	sbuf.hex_dump(std::cerr);
    }

    /* for now we're only looking for TCP; throw away everything else */
    if (ip_header->ip_p != IPPROTO_TCP) {
	DEBUG(50) ("got non-TCP frame -- IP proto %d", ip_header->ip_p);
	return -1;                      // couldn't process
    }

    /* check and see if we got everything.  NOTE: we must use
     * ip_total_len after this, because we may have captured bytes
     * beyond the end of the packet (e.g. ethernet padding).
     */
    size_t ip_len = ntohs(ip_header->ip_len);
    if (pi.ip_datalen < ip_len) {
	DEBUG(6) ("warning: captured only %ld bytes of %ld-byte IP datagram",
		  (long) pi.ip_datalen, (long) ip_len);
    }

    /* XXX - throw away everything but fragment 0; this version doesn't
     * know how to do fragment reassembly.
     */
    if (ntohs(ip_header->ip_off) & 0x1fff) {
	DEBUG(2) ("warning: throwing away IP fragment from X to X");
	return -1;
    }

    /* figure out where the IP header ends */
    size_t ip_header_len = ip_header->ip_hl * 4;

    /* make sure there's some data */
    if (ip_header_len > ip_len) {
	DEBUG(6) ("received truncated IP datagram!");
	return -1;
    }

    /* do TCP processing, faking an ipv6 address  */
    uint16_t ip_payload_len = ip_len - ip_header_len;
    ipaddr src(ip_header->ip_src.addr);
    ipaddr dst(ip_header->ip_dst.addr);
    return process_tcp(src, dst, AF_INET,
                       pi.ip_data + ip_header_len, ip_payload_len,
                       pi);
}
Beispiel #4
0
/**
 * After the flow is finished, put it in an SBUF and process it.
 * if we are doing post-processing.
 * This is called from tcpip::~tcpip() in tcpip.cpp.
 */
void tcpdemux::post_process_capture_flow(std::stringstream &xmladd,
        const std::string &flow_pathname)
{
    int fd2 = retrying_open(flow_pathname,O_RDONLY|O_BINARY,0);
    if(fd2<0) {
        perror("open");
        return;
    }
    sbuf_t *sbuf = sbuf_t::map_file(flow_pathname,pos0_t(flow_pathname),fd2);
    if(sbuf) {
        process_sbuf(scanner_params(scanner_params::scan,*sbuf,*fs,&xmladd));
    }
    ::close(fd2);
}
Beispiel #5
0
sbuf_t *sbuf_t::map_file(const std::string &fname,int fd)
{
    struct stat st;
    if(fstat(fd,&st)){
        close(fd);
        return 0; /* cannot stat */
    }

#ifdef HAVE_MMAP
    uint8_t *buf = (uint8_t *)mmap(0,st.st_size,PROT_READ,MAP_FILE|MAP_SHARED,fd,0);
    bool should_free  = false;
    bool should_unmap = true;
#else
    uint8_t *buf = (uint8_t *)malloc(st.st_size);
    if(buf==0){         /* malloc failed */
        return 0;
    }
    lseek(fd,0,SEEK_SET);               // go to beginning of file
    size_t r = (size_t)read(fd,(void *)buf,st.st_size);
    if(r!=(size_t)st.st_size){
        free((void *)buf);              /* read failed */
        return 0;
    }
    close(fd);
    fd = 0;
    bool should_free = true;
    bool should_unmap = false;
#endif
    sbuf_t *sbuf = new sbuf_t(pos0_t(fname+sbuf_t::map_file_delimiter),
                              buf,
                              st.st_size,
                              st.st_size,
                              fd,
                              should_unmap,
                              should_free,
                              false);   // the caller's job is to close
    return sbuf;
}
Beispiel #6
0
    void Handle80211DataFromAP(const struct timeval& t, const data_hdr_t *hdr, const u_char *rest, int len) {
        if (opt_enforce_80211_frame_checksum && !fcs_ok) return;
#ifdef DEBUG_WIFI
        cout << hdr->sa;
        cout << "  " << "802.11 data from AP:\t" 
             << hdr->sa << " -> " << hdr->da << "\t" << len << endl;
#endif
        struct timeval tv;
        /* TK1: Does the pcap header make sense? */
        /* TK2: How do we get and preserve the the three MAC addresses? */

        printf("DATA_HDRLEN=%d  DATA_WDS_HDRLEN=%d\n",DATA_HDRLEN,DATA_WDS_HDRLEN);

        sbuf_t sb(pos0_t(),rest,len,len,0);
        sb.hex_dump(std::cout);

        rest += 10;                     // where does 10 come from? 
        len -= 10;

        be13::packet_info pi(DLT_IEEE802_11,(const pcap_pkthdr *)0,(const u_char *)0,tvshift(tv,t),rest,len);
        printf("pi.ip_version=%d\n",pi.ip_version());
        process_packet_info(pi);
    }
Beispiel #7
0
static void bulk_process_feature_file(const std::string &fn)
{
    if(ends_with(fn,".txt")==false) return; // don't process binary files
    if(ends_with(fn,"_histogram.txt")==true) return; // ignore histogram files

    const string features(fn.substr(fn.rfind('/')+1,fn.size()-fn.rfind('/')-5));
    const string name(features+": ");
    const string SPACE(" ");
    const string UNKNOWN("UNKNOWN");
    bool tagfile = ends_with(fn,"_tags.txt");
    ifstream f(fn.c_str());
    if(!f.is_open()){
	cerr << "Cannot open tag input file: " << fn << "\n";
	return;
    }
    try {
	string line;
	while(getline(f,line)){
	    if(line.size()==0 || line[0]=='#' || line.substr(0,4)=="\357\273\277#") continue;
	    vector<string> fields = split(line,'\t'); // fields of the feature file
	    if(fields.size()<2) continue;	      // improper formatting
	    std::string &taglocation  = fields[0];
	    std::string &tagtype = fields[1];
	    uint64_t offset = stoi64(taglocation);
	    uint64_t sector =  offset / opt_bulk_block_size;

	    /* If the array hasn't been expanded to the point of this element, expand it with blanks */
	    while(sector > sector_typetags.size()){
		sector_typetags.push_back(sector_typetag()); // expand to fill gap
	    }

	    if(tagfile){		// first pass
		/* Process a tag */
		vector<string> vals  = split(taglocation,':');
		
		if(vals.size()!=2){
		    std::cerr << "Invalid tag file line: " << line << " (size=" << vals.size() << ")\n";
		    exit(1);
		}

		uint32_t len = stoi(vals[1]);

		// If no data for this sector, simply append this type
		// and then continue
		if(sector_typetags.size()==sector){ 
		    sector_typetags.push_back(sector_typetag(len,tagtype,string("")));
		    continue;
		} 

		// We have new data for the same element. Which is better?
		if(sector_typetags[sector].specificity() < sector_typetag::specificity(tagtype)){
		    // New is more specific than the old.
		    // Preserve the old one 
		    sector_typetags[sector].scomment = sector_typetags[sector].stype + string("; ") + sector_typetags[sector].scomment;
		    sector_typetags[sector].stype = tagtype; // specify new tag type
		} else {
		    // New is less specific than the old, so just make new type a comment.
		    sector_typetags[sector].scomment = tagtype + string("; ") + sector_typetags[sector].scomment;
		}
		continue;
	    }
	    /* Process a feature, which will add specificity to the tag */
	    if(sector_typetags.size()==sector){ 
		/* Hm... No tag (and all tags got processed first), so this is unknown */
		sector_typetags.push_back(sector_typetag(opt_bulk_block_size,UNKNOWN,SPACE));
	    } 
	    /* append what we've learned regarding this feature */
	    
	    // If we got an MD5 as field1 and there is a second field, go with that
	    
	    sector_typetag &s = sector_typetags[sector];
	    int field = 1;
	    if(fields.size()>2 && fields[1].size()==32 && fields[2].size()>0 && fields[2][0]=='<'){
		field = 2;		// go with the second field
	    }
	    s.scomment += " " + name + fields[field];
	    
	    // append any XML if it is present
	    if(field==1 && fields.size()>2 && fields[2].size()>0 && fields[2][0]=='<'){
		s.scomment += " " + name + " " + fields[2];
	    }

	    // Scan through the feature indicator table and if we find a match note the type
	    for(int i=0;feature_indicators[i].feature_file_name;i++){
		if(features!=feature_indicators[i].feature_file_name) continue;
		if(feature_indicators[i].feature_content==0
		   || fields[1].find(feature_indicators[i].feature_content)!=string::npos
		   || fields[2].find(feature_indicators[i].feature_content)!=string::npos){
		    s.stype = pos0_t(fields[0]).alphaPart();
		    if(s.stype.size()>1){
			char lastchar = s.stype.at(s.stype.size()-1);
			if(lastchar!='-' && lastchar!='/') s.stype += string("-");
		    }
		    s.stype += feature_indicators[i].dfrws_type;
		}
	    }
	}
    }
    catch (const std::exception &e) {
	cerr << "ERROR: " << e.what() << " processing tagfile " << fn << "\n";
    }
}