Browse code

check RIFF files for MS05-002. Not yet activated.

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1306 77e5149b-7576-45b1-b177-96237e5ba77b

Trog authored on 2005/02/04 19:04:09
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Fri Feb  4 10:02:08 GMT 2005 (trog)
2
+-----------------------------------
3
+  * libclamav/special.c: check RIFF files for MS05-002. Not yet activated.
4
+
1 5
 Thu Feb  3 21:09:34 GMT 2005 (njh)
2 6
 ----------------------------------
3 7
   * libclamav/mbox.c:	Speed improvements in the handling of bounce messages
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2
- *  Copyright (C) 2004 trog@uncon.org
2
+ *  Copyright (C) 2004-2005 trog@uncon.org
3 3
  *
4 4
  *  This program is free software; you can redistribute it and/or modify
5 5
  *  it under the terms of the GNU General Public License as published by
... ...
@@ -25,6 +25,8 @@
25 25
 #include "clamav.h"
26 26
 #include "others.h"
27 27
 
28
+#define FALSE (0)
29
+#define TRUE (1)
28 30
 
29 31
 int cli_check_mydoom_log(int desc, const char **virname)
30 32
 {
... ...
@@ -114,3 +116,115 @@ int cli_check_jpeg_exploit(int fd)
114 114
 		}
115 115
 	}
116 116
 }
117
+
118
+#if WORDS_BIGENDIAN == 0
119
+#define riff_endian_convert_32(v)    (v)
120
+#else
121
+static uint32_t riff_endian_convert_32(uint32_t v)
122
+{
123
+        return ((v >> 24) | ((v & 0x00FF0000) >> 8) |
124
+                ((v & 0x0000FF00) << 8) | (v << 24));
125
+}
126
+#endif
127
+
128
+static int riff_read_chunk(int fd, int big_endian, int rec_level)
129
+{
130
+	uint32_t chunk_id;
131
+	uint32_t chunk_size;
132
+	int length;
133
+	uint32_t list_type;
134
+	off_t offset, cur_offset;
135
+
136
+	if (rec_level > 1000) {
137
+		cli_dbgmsg("riff_read_chunk: recursion level exceeded\n");
138
+		return 0;
139
+	}
140
+	
141
+	length = sizeof(uint32_t);
142
+	if (cli_readn(fd, &chunk_id, length) != length) {
143
+		return 0;
144
+	}
145
+	if (cli_readn(fd, &chunk_size, length) != length) {
146
+		return 0;
147
+	}
148
+	if (big_endian) {
149
+		chunk_size = riff_endian_convert_32(chunk_size);
150
+	}
151
+
152
+	if (memcmp(&chunk_id, "RIFF", 4) == 0) {
153
+		return 0;
154
+	} else if (memcmp(&chunk_id, "RIFX", 4) == 0) {
155
+		return 0;
156
+	}
157
+	
158
+	if ((memcmp(&chunk_id, "LIST", 4) == 0) ||
159
+		 (memcmp(&chunk_id, "PROP", 4) == 0) ||
160
+		 (memcmp(&chunk_id, "FORM", 4) == 0) ||
161
+		 (memcmp(&chunk_id, "CAT ", 4) == 0)) {
162
+		if (cli_readn(fd, &list_type, sizeof(list_type)) != sizeof(list_type)) {
163
+			cli_dbgmsg("riff_read_chunk: read list type failed\n");
164
+			return 0;
165
+		}
166
+		return riff_read_chunk(fd, big_endian, ++rec_level);	
167
+	}
168
+	
169
+	cur_offset = lseek(fd, 0, SEEK_CUR);
170
+	offset = cur_offset + chunk_size;
171
+	/* Check for odd alignment */
172
+	if ((offset & 0x01) == 1) {
173
+		offset++;
174
+	}
175
+	if (offset < cur_offset) {
176
+		return 0;
177
+	}
178
+	if (lseek(fd, offset, SEEK_SET) != offset) {
179
+		return 2;
180
+	}
181
+	return 1;
182
+}
183
+
184
+int cli_check_riff_exploit(int fd)
185
+{
186
+	uint32_t chunk_id;
187
+	uint32_t chunk_size;
188
+	uint32_t form_type;
189
+	int length, big_endian, retval;
190
+	off_t offset;
191
+	
192
+	cli_dbgmsg("in cli_check_riff_exploit()\n");
193
+
194
+	length = sizeof(uint32_t);
195
+	if (cli_readn(fd, &chunk_id, length) != length) {
196
+		return 0;
197
+	}
198
+	if (cli_readn(fd, &chunk_size, length) != length) {
199
+		return 0;
200
+	}
201
+	if (cli_readn(fd, &form_type, length) != length) {
202
+		return 0;
203
+	}
204
+	
205
+	if (memcmp(&chunk_id, "RIFF", 4) == 0) {
206
+		big_endian = FALSE;
207
+	} else if (memcmp(&chunk_id, "RIFX", 4) == 0) {
208
+		big_endian = TRUE;
209
+	} else {
210
+		/* Not a RIFF file */
211
+		return 0;
212
+	}
213
+
214
+	if (big_endian) {
215
+		chunk_size = riff_endian_convert_32(chunk_size);
216
+	}
217
+
218
+	do {
219
+		retval = riff_read_chunk(fd, big_endian, 1);
220
+	} while (retval == 1);
221
+		
222
+	offset = lseek(fd, 0, SEEK_CUR);
223
+
224
+	if (offset < chunk_size) {
225
+		retval = 2;
226
+	};
227
+	return retval;
228
+}