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