1 #ifndef	SIPDUMP_H
2 #define SIPDUMP_H
3 
4 #include <stdio.h>
5 #include <string.h>
6 #include <stdarg.h>
7 
8 /*
9  * Copyright (C) 2007  Martin J. Muench <mjm@codito.de>
10  *
11  * See doc/SIPcrack-LICENSE
12  *
13  * Debug function that is activated through "-DDEBUG" switch
14  */
15 
ic_debug(const char * fmt,...)16 void ic_debug(const char *fmt, ...)
17 {
18 	char buffer[4096];
19 	va_list ap;
20 
21 	memset(buffer, 0, sizeof(buffer));
22 	va_start(ap, fmt);
23 	vsnprintf(buffer, sizeof(buffer) - 1, fmt, ap);
24 	va_end(ap);
25 
26 	fprintf(stderr, "+ %s\n", buffer);
27 }
28 
29 #ifdef DEBUG
30 #define debug(x) ic_debug x;
31 #else
32 #define debug(x) do { } while(1!=1);
33 #endif
34 
35 void ic_debug(const char *fmt, ...);
36 
37 #define VERSION             "0.3"	/* sipdump/sipcrack version */
38 #define DEFAULT_PCAP_FILTER "tcp or udp or vlan"	/* default packet capture filter */
39 
40 /* sip field sizes */
41 #define HOST_MAXLEN       256	/* Max len of hostnames      */
42 #define USER_MAXLEN       128	/* Max len of user names     */
43 #define URI_MAXLEN        256	/* Max len of uri            */
44 #define NONCE_MAXLEN      128	/* Max len of nonce value    */
45 #define CNONCE_MAXLEN     128	/* Max len for cnonce value  */
46 #define NONCECOUNT_MAXLEN   8	/* Max len for nonce count   */
47 #define QOP_MAXLEN         12	/* Max len for qop value     */
48 #define LOGIN_MAXLEN     1024	/* Max len of login entry    */
49 #define ALG_MAXLEN          8	/* Max len of algorithm name */
50 #define METHOD_MAXLEN      16	/* Max len of method string  */
51 
52 /* Hash stuff */
53 #define MD5_LEN            16	/* Len of MD5 binary hash    */
54 #define MD5_LEN_HEX        32	/* Len of MD5 hex hash       */
55 #define PW_MAXLEN          32	/* Max len of password       */
56 
57 #define DYNAMIC_HASH_SIZE USER_MAXLEN + HOST_MAXLEN + 3
58 #define STATIC_HASH_SIZE  NONCE_MAXLEN + CNONCE_MAXLEN + NONCECOUNT_MAXLEN \
59                           + QOP_MAXLEN + MD5_LEN_HEX + 6
60 
61 /* Structure to hold login information */
62 typedef struct {
63 	char server[HOST_MAXLEN];
64 	char client[HOST_MAXLEN];
65 	char user[USER_MAXLEN];
66 	char realm[HOST_MAXLEN];
67 	char method[METHOD_MAXLEN];
68 	char uri[URI_MAXLEN];
69 	char nonce[NONCE_MAXLEN];
70 	char cnonce[NONCE_MAXLEN];
71 	char nonce_count[CNONCE_MAXLEN];
72 	char qop[QOP_MAXLEN];
73 	char algorithm[ALG_MAXLEN];
74 	char hash[MD5_LEN_HEX + 1];
75 } login_t;
76 
77 #include <stdio.h>
78 
79 void *Calloc(size_t);
80 void *Realloc(void *, size_t);
81 char **stringtoarray(char *, char, int *);
82 void get_string_input(char *, size_t, const char *, ...);
83 int is_binary(const unsigned char *, size_t);
84 void init_bin2hex(char[256][2]);
85 void bin_to_hex(char[256][2], const unsigned char *, size_t, char *, size_t);
86 void write_login_data(login_t *, const char *);
87 void update_login_data(login_t *, const char *, const char *);
88 int find_value(const char *, const char *, char *, size_t);
89 void Toupper(char *, size_t);
90 void extract_method(char *, const char *, size_t);
91 
92 /*
93  * Copyright (C) 2007  Martin J. Muench <mjm@codito.de>
94  *
95  * Some small hacked wrapper functions
96  */
97 
98 #include <stdlib.h>
99 #include <string.h>
100 #include <stdarg.h>
101 #include <ctype.h>
102 #include <errno.h>
103 
104 /* malloc() wrapper */
Calloc(size_t size)105 void *Calloc(size_t size)
106 {
107 	void *buffer;
108 
109 	buffer = calloc(size, 1);
110 
111 	if (buffer == NULL) {
112 		fprintf(stderr, "%s:%d: malloc failed\n", __FUNCTION__, __LINE__);
113 		exit(EXIT_FAILURE);
114 	}
115 
116 	return (buffer);
117 }
118 
119 /* realloc() wrapper */
Realloc(void * buffer,size_t size)120 void *Realloc(void *buffer, size_t size)
121 {
122 
123 	buffer = realloc(buffer, size);
124 
125 	if (buffer == NULL) {
126 		fprintf(stderr, "%s:%d: malloc failed\n", __FUNCTION__, __LINE__);
127 		exit(EXIT_FAILURE);
128 	}
129 
130 	return (buffer);
131 }
132 
133 /* convert string to array */
stringtoarray(char * string,char delimiter,int * size)134 char **stringtoarray(char *string, char delimiter, int *size)
135 {
136 	char **array = NULL;
137 	char *ptr, *oldptr;
138 	int flag = 1;
139 	int count;
140 
141 	*size = 0;
142 	ptr = string;
143 
144 	for (count = 0; flag; count++) {
145 		for (oldptr = ptr; *ptr && *ptr != delimiter; (void)*ptr++);
146 		if (!*ptr)
147 			flag = 0;
148 		*ptr++ = 0x00;
149 		(*size)++;
150 
151 		if (!(array = realloc(array, (count + 1) * sizeof(char *)))) {
152 			fprintf(stderr, "realloc failed\n");
153 			exit(1);
154 		}
155 		array[count] = strdup(oldptr);
156 	}
157 	return array;
158 }
159 
160 /* read input from stdin */
get_string_input(char * outbuf,size_t outbuf_len,const char * fmt,...)161 void get_string_input(char *outbuf, size_t outbuf_len, const char *fmt, ...)
162 {
163 	char msg[128];
164 	va_list ap;
165 
166 	memset(msg, 0, sizeof(msg));
167 	va_start(ap, fmt);
168 	vsnprintf(msg, sizeof(msg) - 1, fmt, ap);
169 	va_end(ap);
170 
171 	do {
172 		printf("%s", msg);
173 		fflush(stdout);
174 	} while (!fgets(outbuf, outbuf_len, stdin));
175 
176 	/* Remove newline */
177 	outbuf[strcspn(outbuf, "\r\n")] = 0x00; // works for LF, CR, CRLF, LFCR, ...
178 
179 	return;
180 }
181 
182 /* check whether buffer contains binary characters */
is_binary(const unsigned char * buffer,size_t len)183 int is_binary(const unsigned char *buffer, size_t len)
184 {
185 	int i;
186 
187 	for (i = 0; i < len; i++) {
188 		if (!isascii(buffer[i]))
189 			return 1;
190 	}
191 
192 	return 0;
193 }
194 
195 /* init bin 2 hex table */
init_bin2hex(char bin2hex_table[256][2])196 void init_bin2hex(char bin2hex_table[256][2])
197 {
198 	unsigned i = 0;
199 
200 	for (i = 0; i < 256; i++) {
201 		bin2hex_table[i][0] =
202 		    (((i >> 4) & 0x0F) <=
203 		    0x09) ? (((i >> 4) & 0x0F) + '0') : (((i >> 4) & 0x0F) +
204 		    'a' - 10);
205 		bin2hex_table[i][1] =
206 		    (((i) & 0x0F) <=
207 		    0x09) ? (((i) & 0x0F) + '0') : (((i) & 0x0F) + 'a' - 10);
208 	}
209 
210 	return;
211 }
212 
213 /* convert bin to hex */
bin_to_hex(char bin2hex_table[256][2],const unsigned char * bin_buffer,size_t bin_buffer_size,char * hex_buffer,size_t hex_buffer_size)214 void bin_to_hex(char bin2hex_table[256][2],
215     const unsigned char *bin_buffer,
216     size_t bin_buffer_size, char *hex_buffer, size_t hex_buffer_size)
217 {
218 	unsigned i;
219 
220 	for (i = 0; i < bin_buffer_size; ++i) {
221 		hex_buffer[i * 2] = bin2hex_table[bin_buffer[i]][0];
222 		hex_buffer[i * 2 + 1] = bin2hex_table[bin_buffer[i]][1];
223 	}
224 
225 	hex_buffer[bin_buffer_size * 2] = 0x00;
226 
227 	return;
228 }
229 
230 /* write login data struct to dump file */
write_login_data(login_t * data,const char * file)231 void write_login_data(login_t * data, const char *file)
232 {
233 	FILE *lfile;
234 
235 	debug(("write_login_data() %s", file));
236 
237 	if ((lfile = fopen(file, "a")) == NULL) {
238 		fprintf(stderr, "* Cannot open dump file: %s\n",
239 		    strerror(errno));
240 		return;
241 	}
242 
243 	fprintf(lfile, "%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\n",
244 	    data->server,
245 	    data->client,
246 	    data->user,
247 	    data->realm,
248 	    data->method,
249 	    data->uri,
250 	    data->nonce,
251 	    data->cnonce,
252 	    data->nonce_count, data->qop, data->algorithm, data->hash);
253 
254 	fclose(lfile);
255 
256 	debug(("write_login_data() done"));
257 
258 	return;
259 }
260 
261 /* Update line in dump file with password */
update_login_data(login_t * data,const char * pw,const char * file)262 void update_login_data(login_t * data, const char *pw, const char *file)
263 {
264 	FILE *login_file, *temp_file;
265 	char buffer[2048], orig_string[2048];
266 	char *tempfile;
267 	size_t tempfile_len;
268 
269 	debug(("update_login_data(): %s", file));
270 
271 	tempfile_len = (strlen(file) + strlen(".tmp") + 1);
272 	tempfile = (char *) Calloc(tempfile_len);
273 
274 	snprintf(tempfile, tempfile_len, "%s.tmp", file);
275 
276 	if ((login_file = fopen(file, "r")) == NULL) {
277 		fprintf(stderr, "* Cannot open dump file: %s\n",
278 		    strerror(errno));
279 		free(tempfile);
280 		return;
281 	}
282 
283 	if ((temp_file = fopen(tempfile, "w")) == NULL) {
284 		fprintf(stderr, "* Cannot open temp file: %s\n",
285 		    strerror(errno));
286 		fclose(login_file);
287 		free(tempfile);
288 		return;
289 	}
290 
291 	snprintf(orig_string, sizeof(orig_string),
292 	    "%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\n", data->server,
293 	    data->client, data->user, data->realm, data->method, data->uri,
294 	    data->nonce, data->cnonce, data->nonce_count, data->qop,
295 	    data->algorithm, data->hash);
296 
297 	while ((fgets(buffer, sizeof(buffer), login_file)) != NULL) {
298 		if (!strncmp(buffer, orig_string, sizeof(buffer))) {
299 			fprintf(temp_file,
300 			    "%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\"%s\n",
301 			    data->server, data->client, data->user,
302 			    data->realm, data->method, data->uri, data->nonce,
303 			    data->cnonce, data->nonce_count, data->qop,
304 			    "PLAIN", pw);
305 		} else {
306 			fprintf(temp_file, "%s", buffer);
307 		}
308 	}
309 
310 	fclose(login_file);
311 	fclose(temp_file);
312 
313 	/* rename */
314 	if (rename(tempfile, file) < 0) {
315 		fprintf(stderr, "* Cannot rename tempfile to dump file: %s\n",
316 		    strerror(errno));
317 		free(tempfile);
318 		return;
319 	}
320 
321 	free(tempfile);
322 
323 	debug(("update_login_data() done"));
324 }
325 
326 /* find value in buffer */
find_value(const char * value,const char * buffer,char * outbuf,size_t outbuf_len)327 int find_value(const char *value, const char *buffer, char *outbuf,
328     size_t outbuf_len)
329 {
330 	char *ptr1, *tempbuf;
331 	int i, b;
332 
333 	/* debug(("find_value() %s", value)); */
334 
335 	ptr1 = strstr(buffer, value);
336 	if (ptr1 == NULL)
337 		return -1;
338 	ptr1 += strlen(value);
339 
340 	b = strlen(ptr1);
341 	tempbuf = Calloc(b + 1);
342 
343 	/* value is quoted */
344 	if (ptr1[0] == '"') {
345 		for (i = 1; i < b; i++) {
346 			ptr1++;
347 			if (ptr1[0] == '"')
348 				break;
349 			tempbuf[i - 1] = ptr1[0];
350 		}
351 	}
352 	/* copy till ',', '\r' or '\n' */
353 	else {
354 		for (i = 0; i < b; i++) {
355 			if (ptr1[0] == ',' || ptr1[0] == 0x0d ||
356 			    ptr1[0] == 0x0a)
357 				break;
358 			tempbuf[i] = ptr1[0];
359 			ptr1++;
360 		}
361 	}
362 
363 	strncpy(outbuf, tempbuf, outbuf_len - 1);
364 	outbuf[outbuf_len - 1] = 0;
365 	free(tempbuf);
366 
367 	debug(("find_value: %s'%s'", value, outbuf));
368 
369 	return 0;
370 }
371 
Toupper(char * buffer,size_t buffer_len)372 void Toupper(char *buffer, size_t buffer_len)
373 {
374 	int i;
375 
376 	for (i = 0; i < buffer_len; i++)
377 		buffer[i] = toupper(ARCH_INDEX(buffer[i]));
378 
379 	return;
380 }
381 
extract_method(char * out,const char * in,size_t out_len)382 void extract_method(char *out, const char *in, size_t out_len)
383 {
384 	int i;
385 
386 	debug(("extract_method() begin"));
387 
388 	for (i = 0; i < out_len; i++) {
389 		if (in[i] == ' ')
390 			break;
391 		out[i] = in[i];
392 	}
393 
394 	out[i] = 0x00;
395 
396 	debug(("extract_method(): %s", out));
397 
398 	return;
399 }
400 
401 #endif
402