00001 //--------------------------------------------------------------------------
00002 // Copyright (C) 2014-2017 Cisco and/or its affiliates. All rights reserved.
00003 //
00004 // This program is free software; you can redistribute it and/or modify it
00005 // under the terms of the GNU General Public License Version 2 as published
00006 // by the Free Software Foundation. You may not use, modify or distribute
00007 // this program under any other version of the GNU General Public License.
00008 //
00009 // This program is distributed in the hope that it will be useful, but
00010 // WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License along
00015 // with this program; if not, write to the Free Software Foundation, Inc.,
00016 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017 //--------------------------------------------------------------------------
00018
00019 // wiz_module.cc author Russ Combs <rucombs@cisco.com>
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024
00025 #include "wiz_module.h"
00026
00027 #include "curses.h"
00028 #include "magic.h"
00029
00030 using namespace std;
00031
00032 //-------------------------------------------------------------------------
00033 // wizard module
00034 //-------------------------------------------------------------------------
00035
00036 static const Parameter wizard_hex_param[] =
00037 {
00038 { "hex", Parameter::PT_STRING, nullptr, nullptr,
00039 "sequence of data with wild chars (?)" },
00040
00041 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
00042 };
00043
00044 static const Parameter wizard_hexes_params[] =
00045 {
00046 { "service", Parameter::PT_STRING, nullptr, nullptr,
00047 "name of service" },
00048
00049 { "proto", Parameter::PT_SELECT, "tcp | udp", "tcp",
00050 "protocol to scan" },
00051
00052 { "client_first", Parameter::PT_BOOL, nullptr, "true",
00053 "which end initiates data transfer" },
00054
00055 { "to_server", Parameter::PT_LIST, wizard_hex_param, nullptr,
00056 "sequence of data with wild chars (?)" },
00057
00058 { "to_client", Parameter::PT_LIST, wizard_hex_param, nullptr,
00059 "sequence of data with wild chars (?)" },
00060
00061 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
00062 };
00063
00064 static const Parameter wizard_spell_param[] =
00065 {
00066 { "spell", Parameter::PT_STRING, nullptr, nullptr,
00067 "sequence of data with wild cards (*)" },
00068
00069 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
00070 };
00071
00072 static const Parameter wizard_spells_params[] =
00073 {
00074 { "service", Parameter::PT_STRING, nullptr, nullptr,
00075 "name of service" },
00076
00077 { "proto", Parameter::PT_SELECT, "tcp | udp", "tcp",
00078 "protocol to scan" },
00079
00080 { "client_first", Parameter::PT_BOOL, nullptr, "true",
00081 "which end initiates data transfer" },
00082
00083 { "to_server", Parameter::PT_LIST, wizard_spell_param, nullptr,
00084 "list of initial tokens with wild cards (*)" },
00085
00086 { "to_client", Parameter::PT_LIST, wizard_spell_param, nullptr,
00087 "list of initial tokens with wild cards (*)" },
00088
00089 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
00090 };
00091
00092 static const Parameter s_params[] =
00093 {
00094 { "hexes", Parameter::PT_LIST, wizard_hexes_params, nullptr,
00095 "criteria for binary service identification" },
00096
00097 { "spells", Parameter::PT_LIST, wizard_spells_params, nullptr,
00098 "criteria for text service identification" },
00099
00100 { "curses", Parameter::PT_MULTI, "dce_smb | dce_udp | dce_tcp", nullptr,
00101 "enable service identification based on internal algorithm" },
00102
00103 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
00104 };
00105
00106 WizardModule::WizardModule() : Module(WIZ_NAME, WIZ_HELP, s_params)
00107 {
00108 c2s_hexes = nullptr;
00109 s2c_hexes = nullptr;
00110 c2s_spells = nullptr;
00111 s2c_spells = nullptr;
00112 curses = nullptr;
00113 }
00114
00115 WizardModule::~WizardModule()
00116 {
00117 delete c2s_hexes;
00118 delete s2c_hexes;
00119
00120 delete c2s_spells;
00121 delete s2c_spells;
00122
00123 delete curses;
00124 }
00125
00126 ProfileStats* WizardModule::get_profile() const
00127 { return &wizPerfStats; }
00128
00129 bool WizardModule::set(const char*, Value& v, SnortConfig*)
00130 {
00131 if ( v.is("service") )
00132 service = v.get_string();
00133
00134 // FIXIT-L implement proto and client_first
00135 else if ( v.is("proto") )
00136 return true;
00137
00138 else if ( v.is("client_first") )
00139 return true;
00140
00141 else if ( v.is("hex") )
00142 spells.push_back(v.get_string());
00143
00144 else if ( v.is("spell") )
00145 spells.push_back(v.get_string());
00146
00147 else if ( v.is("curses") )
00148 curses->add_curse(v.get_string());
00149
00150 else
00151 return false;
00152
00153 return true;
00154 }
00155
00156 bool WizardModule::begin(const char* fqn, int, SnortConfig*)
00157 {
00158 if ( !strcmp(fqn, "wizard") )
00159 {
00160 c2s_hexes = new HexBook;
00161 s2c_hexes = new HexBook;
00162
00163 c2s_spells = new SpellBook;
00164 s2c_spells = new SpellBook;
00165
00166 curses = new CurseBook;
00167 }
00168 else if ( !strcmp(fqn, "wizard.hexes") )
00169 hex = true;
00170
00171 else if ( !strcmp(fqn, "wizard.spells") )
00172 hex = false;
00173
00174 else if ( !strcmp(fqn, "wizard.hexes.to_client") )
00175 c2s = false;
00176
00177 else if ( !strcmp(fqn, "wizard.spells.to_client") )
00178 c2s = false;
00179
00180 else if ( !strcmp(fqn, "wizard.hexes.to_server") )
00181 c2s = true;
00182
00183 else if ( !strcmp(fqn, "wizard.spells.to_server") )
00184 c2s = true;
00185
00186 return true;
00187 }
00188
00189 void WizardModule::add_spells(MagicBook* b, string& service)
00190 {
00191 for ( const auto& p : spells )
00192 b->add_spell(p.c_str(), service.c_str());
00193 }
00194
00195 bool WizardModule::end(const char* fqn, int idx, SnortConfig*)
00196 {
00197 if ( idx )
00198 {
00199 service.clear();
00200 return true;
00201 }
00202 if ( !strstr(fqn, "to_client") and !strstr(fqn, "to_server") )
00203 {
00204 return true;
00205 }
00206 if ( hex )
00207 {
00208 if ( c2s )
00209 add_spells(c2s_hexes, service);
00210 else
00211 add_spells(s2c_hexes, service);
00212 }
00213 else
00214 {
00215 if ( c2s )
00216 add_spells(c2s_spells, service);
00217 else
00218 add_spells(s2c_spells, service);
00219 }
00220
00221 spells.clear();
00222 return true;
00223 }
00224
00225 MagicBook* WizardModule::get_book(bool c2s, bool hex)
00226 {
00227 int k = c2s ? 1 : 0;
00228 k |= (hex ? 2 : 0);
00229
00230 MagicBook* b = nullptr;
00231
00232 switch ( k )
00233 {
00234 case 0:
00235 b = s2c_spells;
00236 s2c_spells = nullptr;
00237 break;
00238
00239 case 1:
00240 b = c2s_spells;
00241 c2s_spells = nullptr;
00242 break;
00243
00244 case 2:
00245 b = s2c_hexes;
00246 s2c_hexes = nullptr;
00247 break;
00248
00249 case 3:
00250 b = c2s_hexes;
00251 c2s_hexes = nullptr;
00252 break;
00253 }
00254 return b;
00255 }
00256
00257 CurseBook* WizardModule::get_curse_book()
00258 {
00259 CurseBook* b = curses;
00260 curses = nullptr;
00261 return b;
00262 }
00263
00264 const PegInfo* WizardModule::get_pegs() const
00265 { return wiz_pegs; }
00266
00267 PegCount* WizardModule::get_counts() const
00268 { return (PegCount*)&tstats; }
00269
END OF CODE