suricata
util-file-swf-decompression.c
Go to the documentation of this file.
1 /* Copyright (C) 2017 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /** \file
19  *
20  * \author Giuseppe Longo <giuseppe@glongo.it>
21  *
22  */
23 
24 
25 #include "suricata.h"
26 #include "suricata-common.h"
27 
28 #include "app-layer-htp.h"
29 
32 #include "util-misc.h"
33 #include "util-print.h"
34 
35 #include <zlib.h>
36 
37 #ifdef HAVE_LIBLZMA
38 #include <lzma.h>
39 #endif
40 
41 #define MAX_SWF_DECOMPRESSED_LEN 50000000
42 /*
43  * Return uncompressed file length
44  * in little-endian order
45  */
46 uint32_t FileGetSwfDecompressedLen(const uint8_t *buffer,
47  const uint32_t buffer_len)
48 {
49  if (buffer_len < 8) {
50  return 0;
51  }
52 
53  uint32_t a = buffer[4];
54  uint32_t b = buffer[5];
55  uint32_t c = buffer[6];
56  uint32_t d = buffer[7];
57 
58  uint32_t value = (((a & 0xff) << 24UL) |
59  ((b & 0xff) << 16UL) |
60  ((c & 0xff) << 8UL) |
61  (d & 0xff));
62 
63  uint32_t len = (((value >> 24) & 0x000000FFUL) |
64  ((value >> 8) & 0x0000FF00UL) |
65  ((value << 8) & 0x00FF0000UL) |
66  ((value << 24) & 0xFF000000UL));
67 
68  return MIN(MAX_SWF_DECOMPRESSED_LEN, len);
69 }
70 
71 uint8_t FileGetSwfVersion(const uint8_t *buffer, const uint32_t buffer_len)
72 {
73  if (buffer_len > 3)
74  return buffer[3];
75 
76  return 0;
77 }
78 
79 /* CWS format */
80 /*
81  * | 4 bytes | 4 bytes | n bytes |
82  * | 'CWS' + version | script len | compressed data |
83  */
85  uint8_t *compressed_data, uint32_t compressed_data_len,
86  uint8_t *decompressed_data, uint32_t decompressed_data_len)
87 {
88  int ret = 1;
89  z_stream infstream;
90  infstream.zalloc = Z_NULL;
91  infstream.zfree = Z_NULL;
92  infstream.opaque = Z_NULL;
93 
94  infstream.avail_in = (uInt)compressed_data_len;
95  infstream.next_in = (Bytef *)compressed_data;
96  infstream.avail_out = (uInt)decompressed_data_len;
97  infstream.next_out = (Bytef *)decompressed_data;
98 
99  inflateInit(&infstream);
100  int result = inflate(&infstream, Z_NO_FLUSH);
101  switch(result) {
102  case Z_STREAM_END:
103  break;
104  case Z_OK:
105  break;
106  case Z_DATA_ERROR:
108  ret = 0;
109  break;
110  case Z_STREAM_ERROR:
112  ret = 0;
113  break;
114  case Z_BUF_ERROR:
116  ret = 0;
117  break;
118  default:
120  ret = 0;
121  break;
122  }
123  inflateEnd(&infstream);
124 
125  return ret;
126 }
127 
128 /* ZWS format */
129 /*
130  * | 4 bytes | 4 bytes | 4 bytes | 5 bytes | n bytes | 6 bytes |
131  * | 'ZWS' + version | script len | compressed len | LZMA props | LZMA data | LZMA end marker |
132  */
133 #ifdef HAVE_LIBLZMA
134 int FileSwfLzmaDecompression(DetectEngineThreadCtx *det_ctx,
135  uint8_t *compressed_data, uint32_t compressed_data_len,
136  uint8_t *decompressed_data, uint32_t decompressed_data_len)
137 {
138  int ret = 1;
139  lzma_stream strm = LZMA_STREAM_INIT;
140  lzma_ret result = lzma_alone_decoder(&strm, UINT64_MAX /* memlimit */);
141  if (result != LZMA_OK) {
143  return 0;
144  }
145 
146  strm.avail_in = compressed_data_len;
147  strm.next_in = compressed_data;
148  strm.avail_out = decompressed_data_len;
149  strm.next_out = decompressed_data;
150 
151  result = lzma_code(&strm, LZMA_RUN);
152  switch(result) {
153  case LZMA_STREAM_END:
154  break;
155  case LZMA_OK:
156  break;
157  case LZMA_MEMLIMIT_ERROR:
159  ret = 0;
160  break;
161  case LZMA_OPTIONS_ERROR:
163  ret = 0;
164  break;
165  case LZMA_FORMAT_ERROR:
167  ret = 0;
168  break;
169  case LZMA_DATA_ERROR:
171  ret = 0;
172  break;
173  case LZMA_BUF_ERROR:
175  ret = 0;
176  break;
177  default:
179  ret = 0;
180  break;
181  }
182 
183  lzma_end(&strm);
184  return ret;
185 }
186 #endif /* HAVE_LIBLZMA */
#define MIN(x, y)
void DetectEngineSetEvent(DetectEngineThreadCtx *det_ctx, uint8_t e)
uint32_t FileGetSwfDecompressedLen(const uint8_t *buffer, const uint32_t buffer_len)
#define MAX_SWF_DECOMPRESSED_LEN
uint8_t len
int FileSwfZlibDecompression(DetectEngineThreadCtx *det_ctx, uint8_t *compressed_data, uint32_t compressed_data_len, uint8_t *decompressed_data, uint32_t decompressed_data_len)
uint8_t FileGetSwfVersion(const uint8_t *buffer, const uint32_t buffer_len)