コード例 #1
0
void scan_base64(const class scanner_params &sp,const recursion_control_block &rcb)
{
    assert(sp.sp_version==scanner_params::CURRENT_SP_VERSION);      
    if(sp.phase==scanner_params::PHASE_STARTUP){
        assert(sp.info->si_version==scanner_info::CURRENT_SI_VERSION);
	sp.info->name		= "base64";
        sp.info->author         = "Simson L. Garfinkel";
        sp.info->description    = "scans for Base64-encoded data";
        sp.info->scanner_version= "1.0";

	/* Create the base64 array */
	memset(base64array,0,sizeof(base64array));
	base64array[(int)'+'] = true;
	base64array[(int)'/'] = true;
	for(int ch='a';ch<='z';ch++){ base64array[ch] = true; }
	for(int ch='A';ch<='Z';ch++){ base64array[ch] = true; }
	for(int ch='0';ch<='9';ch++){ base64array[ch] = true; }
	return;	/* No feature files created */
    }
    if(sp.phase==scanner_params::PHASE_SHUTDOWN) return;
    if(sp.phase==scanner_params::PHASE_SCAN){
	const sbuf_t &sbuf = sp.sbuf;

	/* base64 is a newline followed by at least two lines of constant length,
	 * followed by an incomplete line ending with an equal sign.
	 * Lines can be termianted by \n or \r\n. This code simply ignores \r,
	 * which means that you can't have some lines terminated by \n and other
	 * terminated by \n\r.
	 *
	 * Note that this doesn't scan base64-encoded blobs smaller than two lines.
	 * Perhaps we should do that.
	 */
        size_t blockstart = 0;
        bool   inblock    = false;
        size_t prevlen    = 0;
        size_t linecount  = 0;
        size_t pos = 0;
        size_t start = 0;
        size_t len   = 0;
        bool   found_equal = false;
        while(sbuf_getline(sbuf,pos,start,len)){
            //fprintf(stderr,"pos=%zd\n",pos);
            if(sbuf_line_is_base64(sbuf,start,len,found_equal)){
                if(inblock==false){
                    /* First line of a block! */
                    if(len >= minlinewidth){
                        inblock = true;
                        linecount = 1;
                        blockstart = start;
                        prevlen = len;
                    }
                    continue;
                }
                if(len!=prevlen){   // whoops! Lines are different lengths
                    if(found_equal && linecount>1){
                        //fprintf(stderr,"1. linecount=%zd\n",linecount);
                        process(sp,rcb,blockstart,pos-blockstart);
                    }
                    inblock=false;
                    continue;
                }
                linecount++;
                continue;
            }
            /* Ran out of the base64 block */
            if(linecount>2){
                //fprintf(stderr,"2. linecount=%zd\n",linecount);
                process(sp,rcb,blockstart,pos-blockstart);
            }
            inblock = false;
        }
        //fprintf(stderr,"done\n");
    }
}
コード例 #2
0
ファイル: scan_base64.cpp プロジェクト: champ1/bulk_extractor
void scan_base64(const class scanner_params &sp,const recursion_control_block &rcb)
{
    assert(sp.sp_version==scanner_params::CURRENT_SP_VERSION);      
    if(sp.phase==scanner_params::PHASE_STARTUP){
        assert(sp.info->si_version==scanner_info::CURRENT_SI_VERSION);
	sp.info->name		= "base64";
        sp.info->author         = "Simson L. Garfinkel";
        sp.info->description    = "scans for Base64-encoded data";
        sp.info->scanner_version= "1.0";

	/* Create the base64 array */
	memset(base64array,0,sizeof(base64array));
	base64array[(int)'+'] = B64_SYMBOL;
	base64array[(int)'/'] = B64_SYMBOL;
	for(int ch='a';ch<='z';ch++){ base64array[ch] = B64_LOWERCASE; }
	for(int ch='A';ch<='Z';ch++){ base64array[ch] = B64_UPPERCASE; }
	for(int ch='0';ch<='9';ch++){ base64array[ch] = B64_NUMBER; }
	return;	/* No feature files created */
    }
    if(sp.phase==scanner_params::PHASE_SHUTDOWN) return;
    if(sp.phase==scanner_params::PHASE_SCAN){
	const sbuf_t &sbuf = sp.sbuf;

	/* base64 is a newline followed by at least two lines of constant length,
	 * followed by an incomplete line ending with an equal sign.
	 * Lines can be termianted by \n or \r\n. This code simply ignores \r,
	 * which means that you can't have some lines terminated by \n and other
	 * terminated by \n\r.
	 *
	 * Note that this doesn't scan base64-encoded blobs smaller than two lines.
	 * Perhaps we should do that.
	 */
        bool   inblock    = false;      // are we in a base64 block?
        size_t blockstart = 0;          // where the base64 started
        size_t prevlen    = 0;          // length of previous line
        size_t linecount  = 0;          // number of lines in region
        size_t pos = 0;                 // where we are scanning
        size_t line_start = 0;               // start of the line that was found
        size_t line_len   = 0;               // length of the line
        bool   found_equal = false;
        while(sbuf_getline(sbuf,pos,line_start,line_len)){
            //fprintf(stderr,"pos=%zd\n",pos);
            if(sbuf_line_is_base64(sbuf,line_start,line_len,found_equal)){
                if(inblock==false){
                    /* First line of a block! */
                    if(line_len >= minlinewidth){
                        inblock   = true;
                        blockstart= line_start;
                        linecount = 1;
                        prevlen   = line_len;
                    }
                    continue;
                }
                if(line_len!=prevlen){   // whoops! Lines are different lengths
                    if(found_equal && linecount>1){
                        //fprintf(stderr,"1. linecount=%zd\n",linecount);
                        process(sp,rcb,blockstart,pos-blockstart);
                    }
                    inblock=false;
                    continue;
                }
                linecount++;
                continue;
            } else {
                /* Next line is not Base64. If we had more than 2 lines, process them.
                 * Note: hopefully the first line was the beginning of a BASE64 block to address
                 * alignment issues.
                 */
                if(linecount>2 && inblock){
                    //fprintf(stderr,"2. blockstart=%zd line_start=%zd pos=%zd linecount=%zd\n",blockstart,line_start,pos,linecount);
                    process(sp,rcb,blockstart,pos-blockstart);
                }
                inblock = false;
            }
        }
        //fprintf(stderr,"done\n");
    }
}