1 //-------------------------------------------------------------------------- 2 // Copyright (C) 2015-2021 Cisco and/or its affiliates. All rights reserved. 3 // 4 // This program is free software; you can redistribute it and/or modify it 5 // under the terms of the GNU General Public License Version 2 as published 6 // by the Free Software Foundation. You may not use, modify or distribute 7 // this program under any other version of the GNU General Public License. 8 // 9 // This program is distributed in the hope that it will be useful, but 10 // WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 // General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License along 15 // with this program; if not, write to the Free Software Foundation, Inc., 16 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 //-------------------------------------------------------------------------- 18 // ips_http.h author Tom Peters <thopeter@cisco.com> 19 20 #ifndef IPS_HTTP_H 21 #define IPS_HTTP_H 22 23 #include <array> 24 25 #include "profiler/profiler.h" 26 #include "framework/ips_option.h" 27 #include "framework/module.h" 28 #include "framework/range.h" 29 30 #include "http_buffer_info.h" 31 #include "http_enum.h" 32 33 class HttpInspect; 34 35 enum PsIdx { PSI_CLIENT_BODY, PSI_COOKIE, PSI_HEADER, PSI_METHOD, PSI_PARAM, 36 PSI_RAW_BODY, PSI_RAW_COOKIE, PSI_RAW_HEADER, PSI_RAW_REQUEST, PSI_RAW_STATUS, 37 PSI_RAW_TRAILER, PSI_RAW_URI, PSI_STAT_CODE, PSI_STAT_MSG, PSI_TRAILER, 38 PSI_TRUE_IP, PSI_URI, PSI_VERSION, PSI_JS_DATA, PSI_VBA_DATA, 39 PSI_RANGE_NUM_HDRS, PSI_RANGE_NUM_TRAILERS, PSI_MAX }; 40 41 class HttpRuleOptModule : public snort::Module 42 { 43 public: HttpRuleOptModule(const char * key_,const char * help,HttpEnums::HTTP_RULE_OPT rule_opt_index_,snort::CursorActionType cat_,PsIdx psi_)44 HttpRuleOptModule(const char* key_, const char* help, HttpEnums::HTTP_RULE_OPT rule_opt_index_, 45 snort::CursorActionType cat_, PsIdx psi_) 46 : snort::Module(key_, help), key(key_), rule_opt_index(rule_opt_index_), 47 cat(cat_), psi(psi_) {} HttpRuleOptModule(const char * key_,const char * help,HttpEnums::HTTP_RULE_OPT rule_opt_index_,snort::CursorActionType cat_,PsIdx psi_,const snort::Parameter params[])48 HttpRuleOptModule(const char* key_, const char* help, HttpEnums::HTTP_RULE_OPT rule_opt_index_, 49 snort::CursorActionType cat_, PsIdx psi_, const snort::Parameter params[]) 50 : snort::Module(key_, help, params), key(key_), rule_opt_index(rule_opt_index_), 51 cat(cat_), psi(psi_) {} get_profile()52 snort::ProfileStats* get_profile() const override { return &http_ps[psi]; } mod_dtor(snort::Module * m)53 static void mod_dtor(snort::Module* m) { delete m; } 54 bool begin(const char*, int, snort::SnortConfig*) override; 55 bool set(const char*, snort::Value&, snort::SnortConfig*) override; 56 bool end(const char*, int, snort::SnortConfig*) override; 57 get_usage()58 Usage get_usage() const override 59 { return DETECT; } 60 61 private: 62 friend class HttpIpsOption; 63 static THREAD_LOCAL std::array<snort::ProfileStats, PsIdx::PSI_MAX> http_ps; 64 65 struct HttpRuleParaList 66 { 67 public: 68 std::string field; // provide buffer containing specific header field 69 std::string param; // provide buffer containing specific parameter 70 bool nocase; // case insensitive match 71 bool request; // provide buffer from request not response 72 bool with_header; // provide buffer with a later section than it appears in 73 bool with_body; 74 bool with_trailer; 75 bool scheme; // provide buffer with one of the six URI subcomponents 76 bool host; 77 bool port; 78 bool path; 79 bool query; 80 bool fragment; 81 snort::RangeCheck range; 82 83 void reset(); 84 }; 85 86 const char* const key; 87 const HttpEnums::HTTP_RULE_OPT rule_opt_index; 88 const snort::CursorActionType cat; 89 const PsIdx psi; 90 91 HttpRuleParaList para_list; 92 HttpEnums::InspectSection inspect_section; 93 uint64_t sub_id; 94 uint64_t form; 95 }; 96 97 class HttpIpsOption : public snort::IpsOption 98 { 99 public: HttpIpsOption(const HttpRuleOptModule * cm)100 HttpIpsOption(const HttpRuleOptModule* cm) : 101 snort::IpsOption(cm->key, RULE_OPTION_TYPE_BUFFER_SET), 102 key(cm->key), cat(cm->cat), psi(cm->psi), 103 inspect_section(cm->inspect_section), 104 buffer_info(cm->rule_opt_index, cm->sub_id, cm->form, 105 cm->para_list.param, cm->para_list.nocase), range(cm->para_list.range){} get_cursor_type()106 snort::CursorActionType get_cursor_type() const override { return cat; } 107 EvalStatus eval(Cursor&, snort::Packet*) override; 108 uint32_t hash() const override; 109 bool operator==(const snort::IpsOption& ips) const override; 110 bool retry(Cursor&, const Cursor&) override; opt_ctor(snort::Module * m,OptTreeNode *)111 static IpsOption* opt_ctor(snort::Module* m, OptTreeNode*) 112 { return new HttpIpsOption((HttpRuleOptModule*)m); } opt_dtor(snort::IpsOption * p)113 static void opt_dtor(snort::IpsOption* p) { delete p; } 114 115 private: 116 const char* const key; 117 const snort::CursorActionType cat; 118 const PsIdx psi; 119 const HttpEnums::InspectSection inspect_section; 120 HttpBufferInfo buffer_info; 121 const snort::RangeCheck range; 122 }; 123 124 #endif 125 126