From: Josh Date: Thu, 20 Nov 2014 04:36:56 +0000 (-0600) Subject: Snort2Lua fix: content parser can now handle a comman inside of whitespace X-Git-Tag: 3.0.0-233~1183^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4ca9ea2a46ad01015a95239cac18a9ba910e02e0;p=thirdparty%2Fsnort3.git Snort2Lua fix: content parser can now handle a comman inside of whitespace --- diff --git a/tools/snort2lua/rule_states/rule_content.cc b/tools/snort2lua/rule_states/rule_content.cc index a6ca7781d..c045569ed 100644 --- a/tools/snort2lua/rule_states/rule_content.cc +++ b/tools/snort2lua/rule_states/rule_content.cc @@ -20,6 +20,7 @@ #include #include +#include #include "conversion_state.h" #include "helpers/converter.h" @@ -44,6 +45,8 @@ private: bool sticky_buffer_set; bool parse_options(std::istringstream&, std::string, std::string); void add_sticky_buffer(std::istringstream&, std::string buffer); + bool extract_payload(std::istringstream& data_stream, + std::string& option); }; @@ -161,6 +164,32 @@ bool Content::parse_options( return true; } + +template +bool Content::extract_payload(std::istringstream& stream, + std::string& option) +{ + if ( !stream.good() ) + return false; + + std::getline(stream, option, ','); + if (option.empty()) + return false; + + const std::size_t quote = option.find('"'); + if ( (quote != std::string::npos) && (quote == option.rfind('"')) ) + { + std::string tmp; + std::getline(stream, tmp, '"'); + option += "," + tmp + "\""; + std::getline(stream, tmp, ','); + option += tmp; + } + + util::trim(option); + return true; +} + template bool Content::convert(std::istringstream& data_stream) { @@ -174,27 +203,24 @@ bool Content::convert(std::istringstream& data_stream) std::string arg = util::get_rule_option_args(data_stream); std::istringstream arg_stream(arg); - if (!util::get_string(arg_stream, val, ",")) + if (!extract_payload(arg_stream, val) ) { rule_api.bad_rule(data_stream, "content: "); return set_next_rule_state(data_stream); } - rule_api.add_option(*option_name, val); // This first loop parses all of the options between the // content keyword and the first semicolon. - while (util::get_string(arg_stream, keyword, ",")) + while ( extract_payload(arg_stream, keyword) ) { std::istringstream opts(keyword); std::string tmp_str; val = ""; opts >> keyword; // gauranteed to work since get_string is true - - while(opts >> tmp_str) - val += tmp_str + " "; + std::getline(opts, val); util::trim(keyword); util::trim(val); @@ -218,11 +244,7 @@ bool Content::convert(std::istringstream& data_stream) while(util::get_string(subopts, keyword, ":")) { val = std::string(); - std::string tmp_str; - - // get the rest of this option - while(subopts >> tmp_str) - val += tmp_str + " "; + std::getline(subopts, val); // necessary since options contain whitespace util::trim(keyword); diff --git a/tools/snort2lua/tests/snort.conf.in b/tools/snort2lua/tests/snort.conf.in index bc65d84de..b44ddb377 100644 --- a/tools/snort2lua/tests/snort.conf.in +++ b/tools/snort2lua/tests/snort.conf.in @@ -1333,3 +1333,5 @@ threshold gen_id 1, sig_id 7037, type limit, track by_src, count 1, seconds 60 alert ip any any -> any any (msg:"TTL RULE OPTION"; ttl:-4; sid:11111112;) alert ip any any -> any any (msg:"TTL RULE OPTION"; ttl:5-6; sid:11111113;) alert ip any any -> any any (msg:"TTL RULE OPTION"; ttl:7-; sid:11111114;) + +alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (content:"fe, fe, fe, fe, fe, fe, fe,"; msg:"BROWSER-FIREFOX Mozilla Firefox Javascript engine function arguments memory corruption attempt"; flow:to_client,established; file_data; content:"|3B|i<25|3B|i++|29| fe += fe|3B|"; fast_pattern:only; content:"fu=new Function|28 0A|"; content:"fe, fe, fe, fe, fe, fe, fe,"; within:30; metadata:policy balanced-ips drop, policy security-ips drop, service http; reference:bugtraq,19181; reference:cve,2006-3806; classtype:attempted-user; sid:18262; rev:3;)