stream_size, sector_size);
memcpy(temp_data, (file_buf + byte_offset), bytes_to_copy);
- temp_data += sector_size;
+ temp_data += bytes_to_copy;
data_len += bytes_to_copy;
int32_t next_sector = get_next_fat_sector(current_sector);
stream_size, mini_sector_size);
memcpy(temp_data, (file_buf + byte_offset), bytes_to_copy);
- temp_data += mini_sector_size;
+ temp_data += bytes_to_copy;
data_len += bytes_to_copy;
int32_t next_sector = get_next_mini_fat_sector(mini_sector);
set (HELPERS_INCLUDES
${HYPER_HEADERS}
base64_encoder.h
+ buffer_data.h
boyer_moore_search.h
literal_search.h
scratch_allocator.h
base64_encoder.cc
bitop.h
boyer_moore_search.cc
+ buffer_data.cc
chunk.cc
chunk.h
directory.cc
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2021 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// buffer_data.cc author Amarnath Nayak <amarnaya@cisco.com>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "buffer_data.h"
+
+namespace snort
+{
+BufferData::BufferData(int32_t length, const uint8_t* data_, bool own_the_buffer_ = false) :
+ len(length), data(data_), own_the_buffer(own_the_buffer_){}
+
+BufferData::~BufferData()
+{
+ if (own_the_buffer)
+ delete[] data;
+}
+
+int32_t BufferData::length() const
+{
+ return len;
+}
+
+const uint8_t* BufferData::data_ptr() const
+{
+ return data;
+}
+
+void BufferData::set(int32_t length, const uint8_t* data_, bool own_the_buffer_)
+{
+ len = length;
+ data = data_;
+ own_the_buffer = own_the_buffer_;
+}
+
+void BufferData::reset()
+{
+ if (own_the_buffer)
+ delete[] data;
+
+ len = 0;
+ data = nullptr;
+ own_the_buffer = false;
+}
+}
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2021 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// buffer_data.h author Amarnath Nayak <amarnaya@cisco.com>
+#ifndef BUFFER_DATA_H
+#define BUFFER_DATA_H
+
+#include <cstdint>
+
+#include "main/snort_types.h"
+
+namespace snort
+{
+class SO_PUBLIC BufferData
+{
+public:
+ BufferData(int32_t length, const uint8_t* data_, bool own_the_buffer_);
+ BufferData() = default;
+
+ ~BufferData();
+
+ int32_t length() const;
+ const uint8_t* data_ptr() const;
+
+ void set(int32_t length, const uint8_t* data_, bool own_the_buffer_);
+
+ void reset();
+
+ static const BufferData buffer_null;
+
+private:
+ int32_t len = 0;
+ const uint8_t* data = nullptr;
+ bool own_the_buffer = false;
+};
+}
+#endif
return decompress_zip;
}
+void DecodeConfig::set_decompress_vba(bool enabled)
+{
+ decompress_vba = enabled;
+}
+
+bool DecodeConfig::is_decompress_vba() const
+{
+ return decompress_vba;
+}
+
void DecodeConfig::set_decompress_buffer_size(uint32_t size)
{
decompress_buffer_size = size;
ConfigLogger::log_flag("decompress_pdf", decompress_pdf);
ConfigLogger::log_flag("decompress_swf", decompress_swf);
ConfigLogger::log_flag("decompress_zip", decompress_zip);
+ ConfigLogger::log_flag("decompress_vba", decompress_vba);
ConfigLogger::log_value("decompress_buffer_size", decompress_buffer_size);
}
void set_decompress_zip(bool);
bool is_decompress_zip() const;
+ void set_decompress_vba(bool);
+ bool is_decompress_vba() const;
+
void set_decompress_buffer_size(uint32_t);
uint32_t get_decompress_buffer_size() const;
bool decompress_pdf = false;
bool decompress_swf = false;
bool decompress_zip = false;
+ bool decompress_vba = false;
uint32_t decompress_buffer_size = DEFAULT_DECOMP;
int64_t file_depth = MIN_DEPTH;
bool decode_enabled = true;
#include "file_mime_decode.h"
+#include "decompress/file_olefile.h"
#include "utils/util_cstring.h"
#include "decode_b64.h"
using namespace snort;
+const BufferData BufferData::buffer_null;
+
void MimeDecode::init()
{ MimeDecodeContextData::init(); }
if ( (fd_state == nullptr) || (size_in == 0) )
return result;
+ clear_decomp_vba_data();
+
if ( fd_state->State == STATE_COMPLETE )
return result;
default:
buf_out = decompress_buf;
size_out = fd_state->Next_Out - decompress_buf;
+ get_ole_data();
break;
}
return result;
}
+void MimeDecode::get_ole_data()
+{
+ uint8_t* ole_data_ptr;
+ uint32_t ole_len;
+
+ fd_state->get_ole_data(ole_data_ptr, ole_len);
+
+ if (ole_data_ptr)
+ {
+ ole_data.set(ole_len, ole_data_ptr, false);
+
+ //Reset the ole data ptr once it is stored in msg body
+ fd_state->ole_data_reset();
+ }
+}
+
+const BufferData& MimeDecode::get_decomp_vba_data()
+{
+ if (decompressed_vba_data.length() > 0)
+ return decompressed_vba_data;
+
+ if (ole_data.length() <= 0)
+ return BufferData::buffer_null;
+
+ uint8_t* buf = nullptr;
+ uint32_t buf_len = 0;
+
+ VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, CURRENT_PACKET,
+ "Found OLE file. Sending %d bytes for the processing.\n",
+ ole_data.length());
+
+ oleprocess(ole_data.data_ptr(), ole_data.length(), buf, buf_len);
+
+ if (buf && buf_len)
+ decompressed_vba_data.set(buf_len, buf, true);
+
+ return decompressed_vba_data;
+}
+
+void MimeDecode::clear_decomp_vba_data()
+{
+ ole_data.reset();
+ decompressed_vba_data.reset();
+}
+
void MimeDecode::file_decomp_reset()
{
if ( fd_state == nullptr )
bool decompress_pdf = config->is_decompress_pdf();
bool decompress_swf = config->is_decompress_swf();
bool decompress_zip = config->is_decompress_zip();
+ bool decompress_vba = config->is_decompress_vba();
if ( !decompress_pdf && !decompress_swf && !decompress_zip )
return;
fd_state->Modes =
(decompress_pdf ? FILE_PDF_DEFL_BIT : 0) |
(decompress_swf ? (FILE_SWF_ZLIB_BIT | FILE_SWF_LZMA_BIT) : 0) |
- (decompress_zip ? FILE_ZIP_DEFL_BIT : 0);
+ (decompress_zip ? FILE_ZIP_DEFL_BIT : 0) |
+ (decompress_vba ? FILE_VBA_EXTR_BIT : 0);
fd_state->Alert_Callback = nullptr;
fd_state->Alert_Context = nullptr;
fd_state->Compr_Depth = 0;
#include "decompress/file_decomp.h"
#include "framework/counts.h"
+#include "helpers/buffer_data.h"
#include "main/snort_types.h"
#include "mime/decode_base.h"
#include "mime/file_mime_config.h"
DecodeResult decompress_data(const uint8_t* buf_in, uint32_t size_in,
const uint8_t*& buf_out, uint32_t& size_out);
+ const BufferData& get_decomp_vba_data();
+ void clear_decomp_vba_data();
static void init();
private:
+ void get_ole_data();
DecodeType decode_type = DECODE_NONE;
snort::DecodeConfig* config;
DataDecode* decoder = nullptr;
fd_session_t* fd_state = nullptr;
+ BufferData ole_data;
+ BufferData decompressed_vba_data;
};
} // namespace snort
mime_stats = stats;
}
+const BufferData& MimeSession::get_vba_inspect_buf()
+{
+ if (!decode_state)
+ return BufferData::buffer_null;
+
+ return decode_state->get_decomp_vba_data();
+}
+
MailLogState* MimeSession::get_log_state()
{
return log_state;
MailLogState* get_log_state();
void set_mime_stats(MimeStats*);
+ const BufferData& get_vba_inspect_buf();
+
protected:
MimeDecode* decode_state = nullptr;
bool can_start_tls() const override
{ return true; }
+ bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&) override;
+ bool get_fp_buf(snort::InspectionBuffer::Type ibt, snort::Packet* p,
+ snort::InspectionBuffer& b) override;
+
private:
IMAP_PROTO_CONF* config;
};
snort_imap(config, p);
}
+bool Imap::get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
+{
+ switch (ibt)
+ {
+ case InspectionBuffer::IBT_VBA:
+ {
+ IMAPData* imap_ssn = get_session_data(p->flow);
+
+ if (!imap_ssn)
+ return false;
+
+ const BufferData& vba_buf = imap_ssn->mime_ssn->get_vba_inspect_buf();
+
+ if (vba_buf.data_ptr() && vba_buf.length())
+ {
+ b.data = vba_buf.data_ptr();
+ b.len = vba_buf.length();
+ return true;
+ }
+ else
+ return false;
+ }
+
+ default:
+ break;
+ }
+ return false;
+
+}
+bool Imap::get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
+{
+ // Fast pattern buffers only supplied at specific times
+ return get_buf(ibt, p, b);
+}
+
//-------------------------------------------------------------------------
// api stuff
//-------------------------------------------------------------------------
{ "decompress_zip", Parameter::PT_BOOL, nullptr, "false",
"decompress zip files in MIME attachments" },
+ { "decompress_vba", Parameter::PT_BOOL, nullptr, "false",
+ "decompress MS Office Visual Basic for Applications macro files in MIME attachments" },
+
{ "qp_decode_depth", Parameter::PT_INT, "-1:65535", "-1",
"quoted Printable decoding depth (-1 no limit)" },
else if ( v.is("decompress_zip") )
config->decode_conf.set_decompress_zip(v.get_bool());
+ else if ( v.is("decompress_vba") )
+ config->decode_conf.set_decompress_vba(v.get_bool());
+
else if ( v.is("qp_decode_depth") )
config->decode_conf.set_qp_depth(mime_value);
bool can_start_tls() const override
{ return true; }
+ bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&) override;
+ bool get_fp_buf(snort::InspectionBuffer::Type ibt, snort::Packet* p,
+ snort::InspectionBuffer& b) override;
+
private:
POP_PROTO_CONF* config;
};
snort_pop(config, p);
}
+bool Pop::get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
+{
+ // Fast pattern buffers only supplied at specific times
+ switch (ibt)
+ {
+ case InspectionBuffer::IBT_VBA:
+ {
+ POPData* pop_ssn = get_session_data(p->flow);
+
+ if (!pop_ssn)
+ return false;
+
+ const BufferData& vba_buf = pop_ssn->mime_ssn->get_vba_inspect_buf();
+
+ if (vba_buf.data_ptr() && vba_buf.length())
+ {
+ b.data = vba_buf.data_ptr();
+ b.len = vba_buf.length();
+ return true;
+ }
+ else
+ return false;
+ }
+
+ default:
+ break;
+ }
+ return false;
+}
+
+bool Pop::get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
+{
+ return get_buf(ibt, p, b);
+}
+
//-------------------------------------------------------------------------
// api stuff
//-------------------------------------------------------------------------
{ "decompress_zip", Parameter::PT_BOOL, nullptr, "false",
"decompress zip files in MIME attachments" },
+ { "decompress_vba", Parameter::PT_BOOL, nullptr, "false",
+ "decompress MS Office Visual Basic for Applications macro files in MIME attachments" },
+
{ "qp_decode_depth", Parameter::PT_INT, "-1:65535", "-1",
"Quoted Printable decoding depth (-1 no limit)" },
else if ( v.is("decompress_zip") )
config->decode_conf.set_decompress_zip(v.get_bool());
+ else if ( v.is("decompress_vba") )
+ config->decode_conf.set_decompress_vba(v.get_bool());
+
else if ( v.is("qp_decode_depth") )
config->decode_conf.set_qp_depth(mime_value);
void ProcessSmtpCmdsList(const SmtpCmd*);
+ bool get_fp_buf(snort::InspectionBuffer::Type ibt, snort::Packet* p,
+ snort::InspectionBuffer& b) override;
+
private:
SmtpProtoConf* config;
};
snort_smtp(config, p);
}
-bool Smtp::get_buf(
- InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
+bool Smtp::get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
{
- if ( ibt != InspectionBuffer::IBT_ALT )
- return false;
+ // Fast pattern buffers only supplied at specific times
+ switch (ibt)
+ {
+ case InspectionBuffer::IBT_ALT:
+ b.data = SMTP_GetAltBuffer(p, b.len);
+ return (b.data != nullptr);
+
+ case InspectionBuffer::IBT_VBA:
+ {
+ SMTPData* smtp_ssn = get_session_data(p->flow);
- b.data = SMTP_GetAltBuffer(p, b.len);
+ if (!smtp_ssn)
+ return false;
+
+ const BufferData& vba_buf = smtp_ssn->mime_ssn->get_vba_inspect_buf();
+
+ if (vba_buf.data_ptr() && vba_buf.length())
+ {
+ b.data = vba_buf.data_ptr();
+ b.len = vba_buf.length();
+ return true;
+ }
+ else
+ return false;
+ }
+ default:
+ break;
+ }
+ return false;
- return (b.data != nullptr);
}
void Smtp::clear(Packet* p)
config->cmd_config[id].max_line_len = sc->number;
}
+bool Smtp::get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
+{
+ return get_buf(ibt, p, b);
+}
+
//-------------------------------------------------------------------------
// api stuff
//-------------------------------------------------------------------------
{ "decompress_zip", Parameter::PT_BOOL, nullptr, "false",
"decompress zip files in MIME attachments" },
+ { "decompress_vba", Parameter::PT_BOOL, nullptr, "false",
+ "decompress MS Office Visual Basic for Applications macro files in MIME attachments" },
+
{ "email_hdrs_log_depth", Parameter::PT_INT, "0:20480", "1464",
"depth for logging email headers" },
else if ( v.is("decompress_zip") )
config->decode_conf.set_decompress_zip(v.get_bool());
+ else if ( v.is("decompress_vba") )
+ config->decode_conf.set_decompress_vba(v.get_bool());
+
else if ( v.is("email_hdrs_log_depth") )
config->log_config.email_hdrs_log_depth = v.get_uint16();