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 #include <htp/lzma/LzmaDec.h>
38 
39 #define MAX_SWF_DECOMPRESSED_LEN 50000000
40 /*
41  * Return uncompressed file length
42  * in little-endian order
43  */
44 uint32_t FileGetSwfDecompressedLen(const uint8_t *buffer,
45  const uint32_t buffer_len)
46 {
47  if (buffer_len < 8) {
48  return 0;
49  }
50 
51  uint32_t a = buffer[4];
52  uint32_t b = buffer[5];
53  uint32_t c = buffer[6];
54  uint32_t d = buffer[7];
55 
56  uint32_t value = (((a & 0xff) << 24UL) |
57  ((b & 0xff) << 16UL) |
58  ((c & 0xff) << 8UL) |
59  (d & 0xff));
60 
61  uint32_t len = (((value >> 24) & 0x000000FFUL) |
62  ((value >> 8) & 0x0000FF00UL) |
63  ((value << 8) & 0x00FF0000UL) |
64  ((value << 24) & 0xFF000000UL));
65 
66  return MIN(MAX_SWF_DECOMPRESSED_LEN, len);
67 }
68 
69 uint8_t FileGetSwfVersion(const uint8_t *buffer, const uint32_t buffer_len)
70 {
71  if (buffer_len > 3)
72  return buffer[3];
73 
74  return 0;
75 }
76 
77 /* CWS format */
78 /*
79  * | 4 bytes | 4 bytes | n bytes |
80  * | 'CWS' + version | script len | compressed data |
81  */
83  uint8_t *compressed_data, uint32_t compressed_data_len,
84  uint8_t *decompressed_data, uint32_t decompressed_data_len)
85 {
86  int ret = 1;
87  z_stream infstream;
88  infstream.zalloc = Z_NULL;
89  infstream.zfree = Z_NULL;
90  infstream.opaque = Z_NULL;
91 
92  infstream.avail_in = (uInt)compressed_data_len;
93  infstream.next_in = (Bytef *)compressed_data;
94  infstream.avail_out = (uInt)decompressed_data_len;
95  infstream.next_out = (Bytef *)decompressed_data;
96 
97  inflateInit(&infstream);
98  int result = inflate(&infstream, Z_NO_FLUSH);
99  switch(result) {
100  case Z_STREAM_END:
101  break;
102  case Z_OK:
103  break;
104  case Z_DATA_ERROR:
106  ret = 0;
107  break;
108  case Z_STREAM_ERROR:
110  ret = 0;
111  break;
112  case Z_BUF_ERROR:
114  ret = 0;
115  break;
116  default:
118  ret = 0;
119  break;
120  }
121  inflateEnd(&infstream);
122 
123  return ret;
124 }
125 
126 static void *SzAlloc(ISzAllocPtr p, size_t size) { return malloc(size); }
127 static void SzFree(ISzAllocPtr p, void *address) { free(address); }
128 static const ISzAlloc suri_lzma_Alloc = { SzAlloc, SzFree };
129 
130 /* ZWS format */
131 /*
132  * | 4 bytes | 4 bytes | 4 bytes | 5 bytes | n bytes | 6 bytes |
133  * | 'ZWS' + version | script len | compressed len | LZMA props | LZMA data | LZMA end marker |
134  */
136  uint8_t *compressed_data, uint32_t compressed_data_len,
137  uint8_t *decompressed_data, uint32_t decompressed_data_len)
138 {
139  int ret = 0;
140 
141  CLzmaDec strm;
142  LzmaDec_Construct(&strm);
143  ELzmaStatus status;
144 
145  if (compressed_data_len < LZMA_PROPS_SIZE + 8) {
147  return 0;
148  }
149  ret = LzmaDec_Allocate(&strm, compressed_data, LZMA_PROPS_SIZE, &suri_lzma_Alloc);
150  if (ret != SZ_OK) {
152  return 0;
153  }
154  LzmaDec_Init(&strm);
155  compressed_data += LZMA_PROPS_SIZE + 8;
156  compressed_data_len -= LZMA_PROPS_SIZE + 8;
157  size_t inprocessed = compressed_data_len;
158  size_t outprocessed = decompressed_data_len;
159 
160  ret = LzmaDec_DecodeToBuf(&strm, decompressed_data, &outprocessed,
161  compressed_data, &inprocessed, LZMA_FINISH_ANY, &status, MAX_SWF_DECOMPRESSED_LEN);
162 
163  switch(ret) {
164  case SZ_OK:
165  ret = 1;
166  break;
167  case SZ_ERROR_MEM:
169  ret = 0;
170  break;
171  case SZ_ERROR_UNSUPPORTED:
173  ret = 0;
174  break;
175  case SZ_ERROR_DATA:
177  ret = 0;
178  break;
179  case SZ_ERROR_INPUT_EOF:
181  ret = 0;
182  break;
183  default:
185  ret = 0;
186  break;
187  }
188 
189  LzmaDec_Free(&strm, &suri_lzma_Alloc);
190  return ret;
191 }
#define MIN(x, y)
void DetectEngineSetEvent(DetectEngineThreadCtx *det_ctx, uint8_t e)
int FileSwfLzmaDecompression(DetectEngineThreadCtx *det_ctx, uint8_t *compressed_data, uint32_t compressed_data_len, uint8_t *decompressed_data, uint32_t decompressed_data_len)
uint32_t FileGetSwfDecompressedLen(const uint8_t *buffer, const uint32_t buffer_len)
#define MAX_SWF_DECOMPRESSED_LEN
uint8_t address
Definition: decode-ppp.h:312
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)