⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exploit_ber.c

📁 This is the snapshot of Snot Latest Rules
💻 C
字号:
/* * BER support functions *  * Copyright (C) 2007 Sourcefire, Inc. All Rights Reserved *  * Writen by Patrick Mullen <pmullen@sourcefire.com>  * * This file may contain proprietary rules that were created, tested and * certified by Sourcefire, Inc. (the "VRT Certified Rules") as well as * rules that were created by Sourcefire and other third parties and * distributed under the GNU General Public License (the "GPL Rules").  The * VRT Certified Rules contained in this file are the property of * Sourcefire, Inc. Copyright 2005 Sourcefire, Inc. All Rights Reserved. * The GPL Rules created by Sourcefire, Inc. are the property of * Sourcefire, Inc. Copyright 2002-2005 Sourcefire, Inc. All Rights * Reserved.  All other GPL Rules are owned and copyrighted by their * respective owners (please see www.snort.org/contributors for a list of * owners and their respective copyrights).  In order to determine what * rules are VRT Certified Rules or GPL Rules, please refer to the VRT * Certified Rules License Agreement. */#include "sf_snort_plugin_api.h"#include "sf_snort_packet.h"#include "exploit_ber.h"/* Simple macro used to shift a value A bits to the left */#ifndef PM_EXP2#define PM_EXP2(A) 1 << A#endif/* ber_get_size    Interprets the width specifier and returns the value and width   of the size   Returns -1 if not enough payload to read size, -2 if the size   doesn't fit in a u_int32_t, and 0 on success.*/int ber_get_size(SFSnortPacket *sp, const u_int8_t *cursor, u_int32_t *total_len, u_int32_t *size) {   const u_int8_t *end_of_payload;    u_int32_t size_len, retval;   end_of_payload = sp->payload + sp->payload_size;   *total_len = 0;   *size = 0;   if((cursor >= end_of_payload) || (cursor < sp->payload))      return(-1);   if(*cursor & 0x80) {      size_len = *cursor & 0x0F;      *total_len = size_len + 1;      cursor++;      if(cursor + size_len >= end_of_payload)         return(-1);      retval = ber_get_int(cursor, size_len, size);      if(retval < 0)         return(-2); /* size doesn't fit in u_int32_t */   } else {      *size = *cursor;      *total_len = 1;   }   return(0);}/* ber_get_int   Returns the u_int32_t value contained at the pointer after skipping   preceeding NULs.  Returns an error if the data does not fit into   a u_int32_t.*/int ber_get_int(const u_int8_t *data, u_int32_t data_len, u_int32_t *retvalue) {   u_int32_t i;         *retvalue = 0;   /* Jump over NULLs */   i = 0;   while((i < data_len) && (data[i] == 0)) {      i++;   }   if(data_len - i > 4) return(-1); /* Data doesn't fit into u_int32_t */   /* Now find the actual value */   for(;i<data_len;i++) {      *retvalue += data[i] * PM_EXP2(8*(data_len - i - 1));   }   return(0);}/* ber_get_element   Fills a BER_ELEMENT structure with ber element data.   Calling function must verify there is enough payload data before   using ber_element->data.data_ptr.        Return values:    >=0 -- Return value is the number of data bytes available (note           this may be less than the given size if the payload is not	   big enough for all of the data)     <0 -- Incomplete record. -1 means nothing is good.  -2 means the           type is good but the data size is > 0xFFFFFFFF bytes long.*/int ber_get_element(SFSnortPacket *sp, const u_int8_t *cursor, BER_ELEMENT *ber_element) {   const u_int8_t *end_of_payload;   int ret_val = 0;   u_int32_t size_len;   /* temp storage for return values */   u_int32_t data_len;   end_of_payload = sp->payload + sp->payload_size;   /* minimum size is [type][size][data] such as "|02 01 01|" */   if((cursor + 3 >= end_of_payload) || (cursor < sp->payload))      return(-1);      ber_element->type = *cursor;   cursor++;   /* Find the length of the data */   ret_val = ber_get_size(sp, cursor, &size_len, &data_len);   /* ret_val < 0 is a fatal error.  However, if ret_val is -2      it means that the size is > 0xFFFFFFFF.  We want to note      this occurrence as it can be useful in overflow detection      such as CVE-2007-1739.  Just be sure to not use any of      the ber_element values aside from type.  :)   */   if(ret_val < 0)      return(ret_val);   ber_element->total_len = 1 + size_len + data_len;   ber_element->data_len = data_len;   ber_element->data.data_ptr = cursor + size_len;   /* Return the number of data bytes available */   /* Fixed for detection of integer overflow via data_len */   if((cursor + size_len + data_len >= end_of_payload) ||                   (cursor + size_len + data_len <= cursor))      return(end_of_payload - ber_element->data.data_ptr);   else      return(data_len);}     /* ber_extract_int_val   Fills a BER_ELEMENT structure's int_val.   Calling function must verify there is enough payload data before   calling this function.  It is assumed that data_ptr has enough   data to satisfy the value of data_len.   Return values:      0 -- Success     <0 -- Error.  Probably either data_type isn't 0x02 or the data           doesn't fit into a u_int32_t.*/int ber_extract_int_val(BER_ELEMENT *ber_element) {   if(ber_element->type != 0x02)      return -2;   return(ber_get_int(ber_element->data.data_ptr,                      ber_element->data_len,                      &(ber_element->data.int_val)));}/* ber_skip_element   If the element is the specified type, sets the pointer in the   parameter list to the byte after the element.  Note no checks   are made to ensure the pointer is still within the packet.   Return values:      0 -- Success     <0 -- Error*/int ber_skip_element(SFSnortPacket *sp, const u_int8_t **cursor, u_int8_t type) {   int retval;      BER_ELEMENT ber_element;   retval = ber_get_element(sp, *cursor, &ber_element);   if((retval < 0) || (ber_element.type != type) || (retval != ber_element.data_len)) {      return(-1);   } else {      (*cursor) += ber_element.total_len;      return(0);   }}/* ber_point_to_data   If the element is the specified type, sets the pointer in   the parameter list to the first byte of data.  Note no   checks are made to ensure the pointer is still within the   packet.  DO NOT USE THE UPDATED CURSOR W/OUT VERIFICATION.   Return values:      0 -- Success     <0 -- Error*/int ber_point_to_data(SFSnortPacket *sp, const u_int8_t **cursor, u_int8_t type) {   int retval;   BER_ELEMENT ber_element;   retval = ber_get_element(sp, *cursor, &ber_element);   if(retval < 0 || ber_element.type != type) {      return(-1);   } else {      (*cursor) = ber_element.data.data_ptr;      return(0);   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -