/* detection functions */
int rule13308eval(void *p) {
    const u_int8_t *cursor_normal = 0;
    const u_int8_t *beg_of_buffer, *end_of_buffer;

    SFSnortPacket *sp = (SFSnortPacket *) p;
    
    // Base64 stuff
    u_int8_t base64buf[256], decodedbuf[256];
    u_int32_t inputchars, base64bytes, decodedbytes;

    int i;

    if(sp == NULL)
        return RULE_NOMATCH;

    // flow:established, to_server;
    if (checkFlow(p, rule13308options[0]->option_u.flowFlags) <= 0)
        return RULE_NOMATCH;

    // Doing this content match is pretty useless because it's duplicated in our PCRE.
    // But we want to keep the structure for the pattern matcher.
//    // content:"Authorization|3A|", depth 0, nocase, fast_pattern;
//    if (contentMatch(p, rule13308options[1]->option_u.content, &cursor_normal) <= 0)
//        return RULE_NOMATCH;

    // pcre:"^Authorization\x3A\s*Basic[ \t]+", dotall, multiline, nocase;
    if (pcreMatch(p, rule13308options[2]->option_u.pcre, &cursor_normal) <= 0)
        return RULE_NOMATCH;

    if(getBuffer(sp, CONTENT_BUF_NORMALIZED, &beg_of_buffer, &end_of_buffer) != CURSOR_IN_BOUNDS)
        return RULE_NOMATCH;

    // At this point, cursor should point to the start of the auth data
    inputchars = (end_of_buffer > cursor_normal + sizeof(base64buf)) ? sizeof(base64buf) : end_of_buffer - cursor_normal;

    DEBUG_SO(printf("%d input chars: %*s\n", inputchars, inputchars, cursor_normal));

    if(unfold_header(cursor_normal, inputchars, base64buf, sizeof(base64buf), &base64bytes) != 0)
        return RULE_NOMATCH;

    DEBUG_SO(printf("Successfully unfolded header (%s)(%d)\n", base64buf, base64bytes));

    if(base64decode(base64buf, base64bytes, decodedbuf, sizeof(decodedbuf), &decodedbytes) < 0)
        return RULE_NOMATCH;

    DEBUG_SO(printf("Successfully base64 decoded (%s)(%d)\n", decodedbuf, decodedbytes));
  
    for(i=0; i<decodedbytes; i++) {
        DEBUG_SO(printf("checking byte: %c\n", decodedbuf[i]));
        if(decodedbuf[i] == '%') {
            return RULE_MATCH;
        } else if(decodedbuf[i] == ':') {
            // Separator between username:password
            return RULE_NOMATCH;
        }
    }        
        
    return RULE_NOMATCH;
}
예제 #2
0
파일: encode_rfc2047.c 프로젝트: dscho/nmh
int
encode_rfc2047(const char *name, char **value, int encoding,
	       const char *charset)
{
    int i, asciicount = 0, eightbitcount = 0, qpspecialcount = 0;
    char *p;

    /*
     * First, check to see if we even need to encode the header
     */

    for (p = *value; *p != '\0'; p++) {
	if (isascii((unsigned char) *p)) {
	    asciicount++;
	    if (qpspecial((unsigned char) *p))
	    	qpspecialcount++;
	} else
	    eightbitcount++;
    }

    if (eightbitcount == 0)
    	return 0;

    /*
     * Some rules from RFC 2047:
     *
     * - Encoded words cannot be more than 75 characters long
     * - Multiple "long" encoded words must be on new lines.
     *
     * Also, we're not permitted to encode email addresses, so
     * we need to actually _parse_ email addresses and only encode
     * the right bits.  
     */

    /*
     * If charset was NULL, then get the value from the locale.  But
     * we reject it if it returns US-ASCII
     */

    if (charset == NULL)
    	charset = write_charset_8bit();

    if (strcasecmp(charset, "US-ASCII") == 0) {
    	advise(NULL, "Cannot use US-ASCII with 8 bit characters in header");
	return 1;
    }

    /*
     * If we have an address header, then we need to parse the addresses
     * and only encode the names or comments.  Otherwise, handle it normally.
     */

    for (i = 0; address_headers[i]; i++) {
    	if (strcasecmp(name, address_headers[i]) == 0)
	    return field_encode_address(name, value, encoding, charset);
    }

    /*
     * On the encoding we choose, and the specifics of encoding:
     *
     * - If a specified encoding is passed in, we use that.
     * - Otherwise, pick which encoding is shorter.
     *
     * We don't quite handle continuation right here, but it should be
     * pretty close.
     */

    if (encoding == CE_UNKNOWN)
        encoding = pref_encoding(asciicount, qpspecialcount, eightbitcount);

    unfold_header(value, asciicount + eightbitcount);

    switch (encoding) {

    case CE_BASE64:
    	return field_encode_base64(name, value, charset);

    case CE_QUOTED:
	return field_encode_quoted(name, value, charset, asciicount,
				   eightbitcount + qpspecialcount, 0);

    default:
    	advise(NULL, "Internal error: unknown RFC-2047 encoding type");
	return 1;
    }
}