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 
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  memset(&infstream, 0, sizeof(infstream));
89  infstream.zalloc = Z_NULL;
90  infstream.zfree = Z_NULL;
91  infstream.opaque = Z_NULL;
92 
93  infstream.avail_in = (uInt)compressed_data_len;
94  infstream.next_in = (Bytef *)compressed_data;
95  infstream.avail_out = (uInt)decompressed_data_len;
96  infstream.next_out = (Bytef *)decompressed_data;
97 
98  int result = inflateInit(&infstream);
99  if (result != Z_OK) {
101  return 0;
102  }
103 
104  result = inflate(&infstream, Z_NO_FLUSH);
105  switch(result) {
106  case Z_STREAM_END:
107  break;
108  case Z_OK:
109  break;
110  case Z_DATA_ERROR:
112  ret = 0;
113  break;
114  case Z_STREAM_ERROR:
116  ret = 0;
117  break;
118  case Z_BUF_ERROR:
120  ret = 0;
121  break;
122  default:
124  ret = 0;
125  break;
126  }
127  inflateEnd(&infstream);
128 
129  return ret;
130 }
131 
132 static void *SzAlloc(ISzAllocPtr p, size_t size) { return malloc(size); }
133 static void SzFree(ISzAllocPtr p, void *address) { free(address); }
134 static const ISzAlloc suri_lzma_Alloc = { SzAlloc, SzFree };
135 
136 /* ZWS format */
137 /*
138  * | 4 bytes | 4 bytes | 4 bytes | 5 bytes | n bytes | 6 bytes |
139  * | 'ZWS' + version | script len | compressed len | LZMA props | LZMA data | LZMA end marker |
140  */
142  uint8_t *compressed_data, uint32_t compressed_data_len,
143  uint8_t *decompressed_data, uint32_t decompressed_data_len)
144 {
145  int ret = 0;
146 
147  CLzmaDec strm;
148  LzmaDec_Construct(&strm);
149  ELzmaStatus status;
150 
151  if (compressed_data_len < LZMA_PROPS_SIZE + 8) {
153  return 0;
154  }
155  ret = LzmaDec_Allocate(&strm, compressed_data, LZMA_PROPS_SIZE, &suri_lzma_Alloc);
156  if (ret != SZ_OK) {
158  return 0;
159  }
160  LzmaDec_Init(&strm);
161  compressed_data += LZMA_PROPS_SIZE + 8;
162  compressed_data_len -= LZMA_PROPS_SIZE + 8;
163  size_t inprocessed = compressed_data_len;
164  size_t outprocessed = decompressed_data_len;
165 
166  ret = LzmaDec_DecodeToBuf(&strm, decompressed_data, &outprocessed,
167  compressed_data, &inprocessed, LZMA_FINISH_ANY, &status, MAX_SWF_DECOMPRESSED_LEN);
168 
169  switch(ret) {
170  case SZ_OK:
171  ret = 1;
172  break;
173  case SZ_ERROR_MEM:
175  ret = 0;
176  break;
177  case SZ_ERROR_UNSUPPORTED:
179  ret = 0;
180  break;
181  case SZ_ERROR_DATA:
183  ret = 0;
184  break;
185  case SZ_ERROR_INPUT_EOF:
187  ret = 0;
188  break;
189  default:
191  ret = 0;
192  break;
193  }
194 
195  LzmaDec_Free(&strm, &suri_lzma_Alloc);
196  return ret;
197 }
MAX_SWF_DECOMPRESSED_LEN
#define MAX_SWF_DECOMPRESSED_LEN
Definition: util-file-swf-decompression.c:39
len
uint8_t len
Definition: app-layer-dnp3.h:2
FILE_DECODER_EVENT_Z_UNKNOWN_ERROR
@ FILE_DECODER_EVENT_Z_UNKNOWN_ERROR
Definition: detect.h:1259
DetectEngineSetEvent
void DetectEngineSetEvent(DetectEngineThreadCtx *det_ctx, uint8_t e)
Definition: detect-engine.c:4642
MIN
#define MIN(x, y)
Definition: suricata-common.h:372
FILE_DECODER_EVENT_Z_BUF_ERROR
@ FILE_DECODER_EVENT_Z_BUF_ERROR
Definition: detect.h:1258
FILE_DECODER_EVENT_LZMA_FORMAT_ERROR
@ FILE_DECODER_EVENT_LZMA_FORMAT_ERROR
Definition: detect.h:1263
FileGetSwfVersion
uint8_t FileGetSwfVersion(const uint8_t *buffer, const uint32_t buffer_len)
Definition: util-file-swf-decompression.c:69
FileSwfLzmaDecompression
int FileSwfLzmaDecompression(DetectEngineThreadCtx *det_ctx, uint8_t *compressed_data, uint32_t compressed_data_len, uint8_t *decompressed_data, uint32_t decompressed_data_len)
Definition: util-file-swf-decompression.c:141
app-layer-htp.h
DetectEngineThreadCtx_
Definition: detect.h:1034
util-print.h
FILE_DECODER_EVENT_LZMA_UNKNOWN_ERROR
@ FILE_DECODER_EVENT_LZMA_UNKNOWN_ERROR
Definition: detect.h:1266
FILE_DECODER_EVENT_LZMA_OPTIONS_ERROR
@ FILE_DECODER_EVENT_LZMA_OPTIONS_ERROR
Definition: detect.h:1262
FileSwfZlibDecompression
int FileSwfZlibDecompression(DetectEngineThreadCtx *det_ctx, uint8_t *compressed_data, uint32_t compressed_data_len, uint8_t *decompressed_data, uint32_t decompressed_data_len)
Definition: util-file-swf-decompression.c:82
suricata-common.h
FILE_DECODER_EVENT_Z_DATA_ERROR
@ FILE_DECODER_EVENT_Z_DATA_ERROR
Definition: detect.h:1256
FILE_DECODER_EVENT_LZMA_BUF_ERROR
@ FILE_DECODER_EVENT_LZMA_BUF_ERROR
Definition: detect.h:1265
FILE_DECODER_EVENT_LZMA_DATA_ERROR
@ FILE_DECODER_EVENT_LZMA_DATA_ERROR
Definition: detect.h:1264
util-file-swf-decompression.h
util-file-decompression.h
address
uint8_t address
Definition: decode-ppp.h:0
FILE_DECODER_EVENT_LZMA_MEMLIMIT_ERROR
@ FILE_DECODER_EVENT_LZMA_MEMLIMIT_ERROR
Definition: detect.h:1261
suricata.h
FileGetSwfDecompressedLen
uint32_t FileGetSwfDecompressedLen(const uint8_t *buffer, const uint32_t buffer_len)
Definition: util-file-swf-decompression.c:44
util-misc.h
FILE_DECODER_EVENT_Z_STREAM_ERROR
@ FILE_DECODER_EVENT_Z_STREAM_ERROR
Definition: detect.h:1257
FILE_DECODER_EVENT_LZMA_DECODER_ERROR
@ FILE_DECODER_EVENT_LZMA_DECODER_ERROR
Definition: detect.h:1260