mirror of
https://github.com/openappsec/openappsec.git
synced 2025-09-30 11:44:29 +03:00
My 11th 2023 update
This commit is contained in:
143
components/security_apps/ips/ips_entry.cc
Normal file
143
components/security_apps/ips/ips_entry.cc
Normal file
@@ -0,0 +1,143 @@
|
||||
#include "ips_entry.h"
|
||||
#include "ips_signatures.h"
|
||||
#include "ips_configuration.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "common.h"
|
||||
#include "i_keywords_rule.h"
|
||||
#include "helper.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace IPSHelper;
|
||||
|
||||
USE_DEBUG_FLAG(D_IPS);
|
||||
|
||||
static const map<string, IPSConfiguration::Context> default_conf_mapping = {
|
||||
{ "HTTP_METHOD", IPSConfiguration::Context(IPSConfiguration::ContextType::KEEP, 0) },
|
||||
{ "HTTP_COMPLETE_URL_DECODED", IPSConfiguration::Context(IPSConfiguration::ContextType::KEEP, 0) },
|
||||
{ "HTTP_PATH_DECODED", IPSConfiguration::Context(IPSConfiguration::ContextType::KEEP, 0) },
|
||||
{ "HTTP_QUERY_DECODED", IPSConfiguration::Context(IPSConfiguration::ContextType::KEEP, 0) },
|
||||
{ "HTTP_PROTOCOL", IPSConfiguration::Context(IPSConfiguration::ContextType::KEEP, 0) },
|
||||
{ "HTTP_REQUEST_HEADER", IPSConfiguration::Context(IPSConfiguration::ContextType::KEEP, 0) },
|
||||
{ "HTTP_REQUEST_BODY", IPSConfiguration::Context(IPSConfiguration::ContextType::HISTORY, 1000) },
|
||||
{ "HTTP_RESPONSE_CODE", IPSConfiguration::Context(IPSConfiguration::ContextType::KEEP, 0) },
|
||||
{ "HTTP_RESPONSE_HEADER", IPSConfiguration::Context(IPSConfiguration::ContextType::KEEP, 0) },
|
||||
{ "HTTP_RESPONSE_BODY", IPSConfiguration::Context(IPSConfiguration::ContextType::HISTORY, 1000) }
|
||||
};
|
||||
|
||||
static const IPSConfiguration default_conf(default_conf_mapping);
|
||||
|
||||
IPSEntry::IPSEntry() : TableOpaqueSerialize<IPSEntry>(this) {}
|
||||
|
||||
void
|
||||
IPSEntry::upon(const ParsedContext &)
|
||||
{
|
||||
}
|
||||
|
||||
ParsedContextReply
|
||||
IPSEntry::respond(const ParsedContext &parsed)
|
||||
{
|
||||
const auto &name = parsed.getName();
|
||||
auto buf = parsed.getBuffer();
|
||||
|
||||
dbgDebug(D_IPS) << "Entrying context " << name;
|
||||
dbgTrace(D_IPS) << "Context Content " << dumpHex(buf);
|
||||
|
||||
auto config = getConfigurationWithDefault(default_conf, "IPS", "IpsConfigurations").getContext(name);
|
||||
if (config.getType() == IPSConfiguration::ContextType::HISTORY) {
|
||||
buf = past_contexts[name] + buf;
|
||||
}
|
||||
ctx.registerValue(I_KeywordsRule::getKeywordsRuleTag(), name);
|
||||
ctx.registerValue(name, buf);
|
||||
|
||||
ctx.activate();
|
||||
auto &signatures = getConfigurationWithDefault(IPSSignatures(), "IPS", "IpsProtections");
|
||||
bool should_drop = signatures.isMatchedPrevent(parsed.getName(), buf);
|
||||
auto &snort_signatures = getConfigurationWithDefault(SnortSignatures(), "IPSSnortSigs", "SnortProtections");
|
||||
should_drop |= snort_signatures.isMatchedPrevent(parsed.getName(), buf);
|
||||
ctx.deactivate();
|
||||
|
||||
switch(config.getType()) {
|
||||
case IPSConfiguration::ContextType::NORMAL: {
|
||||
ctx.unregisterKey<Buffer>(name);
|
||||
break;
|
||||
}
|
||||
case IPSConfiguration::ContextType::KEEP: {
|
||||
past_contexts[name] += buf;
|
||||
ctx.registerValue(name, past_contexts[name]);
|
||||
break;
|
||||
}
|
||||
case IPSConfiguration::ContextType::HISTORY: {
|
||||
if (buf.size() > config.getHistorySize()) buf.keepTail(config.getHistorySize());
|
||||
ctx.registerValue(name, buf);
|
||||
past_contexts[name] = buf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dbgDebug(D_IPS) << "Return " << (should_drop ? "drop" : "continue");
|
||||
|
||||
return should_drop ? ParsedContextReply::DROP : ParsedContextReply::ACCEPT;
|
||||
}
|
||||
|
||||
Buffer
|
||||
IPSEntry::getBuffer(const string &name) const
|
||||
{
|
||||
auto elem = past_contexts.find(name);
|
||||
if (elem != past_contexts.end()) return elem->second;
|
||||
|
||||
for (auto &p : pending_contexts) {
|
||||
if (p.first == name) return p.second;
|
||||
}
|
||||
|
||||
return Buffer();
|
||||
}
|
||||
|
||||
void
|
||||
IPSEntry::setTransactionData(const Buffer &key, const Buffer &value)
|
||||
{
|
||||
transaction_data[key] = value;
|
||||
}
|
||||
|
||||
Maybe<Buffer>
|
||||
IPSEntry::getTransactionData(const Buffer &key) const
|
||||
{
|
||||
map<Buffer, Buffer>::const_iterator iter = transaction_data.find(key);
|
||||
|
||||
if (iter == transaction_data.end()) {
|
||||
return genError("Http header value not found");
|
||||
}
|
||||
|
||||
return iter->second;
|
||||
|
||||
}
|
||||
|
||||
string
|
||||
IPSEntry::name()
|
||||
{
|
||||
return "IPS";
|
||||
}
|
||||
|
||||
unique_ptr<TableOpaqueBase>
|
||||
IPSEntry::prototype()
|
||||
{
|
||||
return make_unique<IPSEntry>();
|
||||
}
|
||||
|
||||
uint
|
||||
IPSEntry::currVer()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint
|
||||
IPSEntry::minVer()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
IPSEntry::addPendingContext(const std::string &name, const Buffer &buffer)
|
||||
{
|
||||
pending_contexts.emplace_back(name, buffer);
|
||||
}
|
Reference in New Issue
Block a user