· 8 years ago · Apr 17, 2018, 03:42 AM
1l public under the following terms:
2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted.
4 *
5 * Huge thanks to Marc Bevand <m.bevand (at) gmail.com> for releasing unrarhp
6 * (http://www.zorinaq.com/unrarhp/) and documenting the RAR encryption scheme.
7 * This patch is made possible by unrarhp's documentation.
8 *
9 * Usage:
10 *
11 * 1. Run rar2john on rar file(s) as "rar2john [rar files]".
12 * Output is written to standard output.
13 * 2. Run JtR on the output generated by rar2john as "john [output file]".
14 *
15 * Output Line Format:
16 *
17 * For type = 0 for files encrypted with "rar -hp ..." option
18 * archive_name:$RAR3$*type*hex(salt)*hex(partial-file-contents):type::::archive_name
19 *
20 * For type = 1 for files encrypted with "rar -p ..." option
21 * archive_name:$RAR3$*type*hex(salt)*hex(crc)*PACK_SIZE*UNP_SIZE*0*archive_name*offset-for-ciphertext*method:type::file_name
22 *
23 * or
24 *
25 * archive_name:$RAR3$*type*hex(salt)*hex(crc)*PACK_SIZE*UNP_SIZE*1*hex(full encrypted file)*method:type::file_name
26 *
27 * TODO:
28 * Possibly support some file magics (see zip2john)
29 *
30 * FIXED:
31 * Archive starting with a directory is currently not read (skip it)
32 * Archive starting with a plaintext file is currently not read (skip it)
33 * Pick smallest possible file in case of -p mode, just like pkzip do
34 * If any of the files is uncompressed, this is preferred even if larger
35 * Add METHOD to output
36 *
37 */
38
39#include <stdint.h>
40#include <stdio.h>
41#include <stdlib.h>
42#if !AC_BUILT || HAVE_LIMITS_H
43#include <limits.h>
44#endif
45#include <errno.h>
46#include <string.h>
47#if (!AC_BUILT || HAVE_UNISTD_H) && !_MSC_VER
48#include <unistd.h>
49#endif
50
51#include "jumbo.h"
52#include "common.h"
53#include "arch.h"
54#include "params.h"
55#include "crc32.h"
56#include "unicode.h"
57#include "base64_convert.h"
58#include "sha2.h"
59#include "rar2john.h"
60#ifdef _MSC_VER
61#include "missing_getopt.h"
62#endif
63#include "memdbg.h"
64
65#define CHUNK_SIZE 4096
66
67static int verbose;
68
69static void hexdump(const void *msg, void *x, unsigned int size)
70{
71 unsigned int i;
72
73 printf("%s : ", (char *)msg);
74 for (i=0;i<size;i++)
75 {
76 printf("%.2x", ((unsigned char*)x)[i]);
77 if ( (i%4)==3 )
78 printf(" ");
79 }
80 printf("\n");
81}
82
83static int process_file5(const char *archive_name);
84
85static int check_fread(const size_t buf_size, const size_t size, const size_t nmemb)
86{
87 if (buf_size < size * nmemb) {
88 fprintf(stderr, "Error: check_fread(buf_size="Zu", size="Zu", nmemb="Zu") failed, "
89 "buf_size is smaller than size * nmemb.\n",
90 buf_size, size, nmemb);
91 return 0;
92 }
93 return 1;
94}
95
96/* Derived from unrar's encname.cpp */
97static void DecodeFileName(unsigned char *Name, unsigned char *EncName,
98 size_t EncSize, UTF16 *NameW, size_t MaxDecSize)
99{
100 unsigned char Flags = 0;
101 unsigned int FlagBits = 0;
102 size_t EncPos = 0, DecPos = 0;
103 unsigned char HighByte = EncName[EncPos++];
104
105 MaxDecSize /= sizeof(UTF16);
106
107 while (EncPos < EncSize - 1 && DecPos < MaxDecSize - 1)
108 {
109 if (FlagBits == 0)
110 {
111 Flags = EncName[EncPos++];
112 FlagBits = 8;
113 }
114 switch(Flags >> 6)
115 {
116 case 0:
117#if ARCH_LITTLE_ENDIAN
118 NameW[DecPos++] = EncName[EncPos++];
119#else
120 NameW[DecPos++] = EncName[EncPos++] << 8;
121#endif
122 break;
123 case 1:
124#if ARCH_LITTLE_ENDIAN
125 NameW[DecPos++] = EncName[EncPos++] + (HighByte << 8);
126#else
127 NameW[DecPos++] = (EncName[EncPos++] << 8) + HighByte;
128#endif
129 break;
130 case 2:
131#if ARCH_LITTLE_ENDIAN
132 NameW[DecPos++] = EncName[EncPos] +
133 (EncName[EncPos+1]<<8);
134#else
135 NameW[DecPos++] = (EncName[EncPos] << 8) +
136 EncName[EncPos+1];
137#endif
138 EncPos+=2;
139 break;
140 case 3:
141 {
142 int Length = EncName[EncPos++];
143 if (Length & 0x80)
144 {
145 unsigned char Correction = EncName[EncPos++];
146 for (Length = (Length & 0x7f) + 2;
147 Length>0 && DecPos < MaxDecSize;
148 Length--, DecPos++)
149#if ARCH_LITTLE_ENDIAN
150 NameW[DecPos] = ((Name[DecPos] +
151 Correction) & 0xff) + (HighByte << 8);
152#else
153 NameW[DecPos] = (((Name[DecPos] +
154 Correction) & 0xff) << 8) + HighByte;
155#endif
156 }
157 else
158 for (Length += 2;
159 Length>0 && DecPos < MaxDecSize;
160 Length--,DecPos++)
161#if ARCH_LITTLE_ENDIAN
162 NameW[DecPos] = Name[DecPos];
163#else
164 NameW[DecPos] = Name[DecPos] << 8;
165#endif
166 }
167 break;
168 }
169 Flags <<= 2;
170 FlagBits -= 2;
171 }
172 NameW[DecPos < MaxDecSize ? DecPos : MaxDecSize - 1] = 0;
173}
174
175static void process_file(const char *archive_name)
176{
177 FILE *fp;
178 unsigned char marker_block[7];
179 unsigned char archive_header_block[13];
180 unsigned char file_header_block[40];
181 int i, count, type;
182 size_t bestsize = 0;
183 char *base_aname;
184 unsigned char buf[CHUNK_SIZE];
185 uint16_t archive_header_head_flags, file_header_head_flags, head_size;
186 unsigned char *pos;
187 int diff;
188 int found = 0;
189 char path[PATH_BUFFER_SIZE];
190 char *gecos, *best = NULL;
191 int best_len = 0, gecos_len = 0;
192
193 gecos = mem_calloc(1, LINE_BUFFER_SIZE);
194
195 strnzcpy(path, archive_name, sizeof(path));
196 base_aname = basename(path);
197 errno = 0;
198
199 if (!(fp = fopen(archive_name, "rb"))) {
200 fprintf(stderr, "! %s: %s\n", archive_name, strerror(errno));
201 goto err;
202 }
203 /* marker block */
204 memset(marker_block, 0, 7);
205 if (fread(marker_block, 7, 1, fp) != 1) {
206 fprintf(stderr, "%s: Error: read failed: %s.\n",
207 archive_name, strerror(errno));
208 goto err;
209 }
210
211 if (memcmp(marker_block, "\x52\x61\x72\x21\x1a\x07\x00", 7)) { /* handle SFX archives */
212 if (memcmp(marker_block, "MZ", 2) == 0) {
213 /* jump to "Rar!" signature */
214 while (!feof(fp)) {
215 count = fread(buf, 1, CHUNK_SIZE, fp);
216 if ( (pos = memmem(buf, count, "\x52\x61\x72\x21\x1a\x07\x00", 7))) {
217 diff = count - (pos - buf);
218 jtr_fseek64(fp, - diff, SEEK_CUR);
219 jtr_fseek64(fp, 7, SEEK_CUR);
220 found = 1;
221 break;
222 }
223 if (feof(fp)) //We shold examine the EOF before seek back
224 break;
225 jtr_fseek64(fp, -6, SEEK_CUR);
226 }
227 if (!found) {
228 if (process_file5(archive_name))
229 return;
230 fprintf(stderr, "! %s: Not a RAR file\n", archive_name);
231 goto err;
232 }
233 }
234 else {
235 /* try to detect RAR 5 files */
236 fclose(fp);
237 fp = NULL;
238 MEM_FREE(best);
239 MEM_FREE(gecos);
240 if (process_file5(archive_name))
241 return;
242 fprintf(stderr, "! %s: Not a RAR file\n", archive_name);
243 goto err;
244 }
245 }
246
247 /* archive header block */
248 if (fread(archive_header_block, 13, 1, fp) != 1) {
249 fprintf(stderr, "%s: Error: read failed: %s.\n",
250 archive_name, strerror(errno));
251 goto err;
252 }
253 if (archive_header_block[2] != 0x73) {
254 fprintf(stderr, "%s: Error: archive_header_block[2] must be 0x73.\n",
255 archive_name);
256 goto err;
257 }
258
259 /* find encryption mode used (called type in output line format) */
260 archive_header_head_flags =
261 archive_header_block[4] << 8 | archive_header_block[3];
262 if (archive_header_head_flags & 0x0080) { /* file header block is encrypted */
263 type = 0; /* RAR file was created using -hp flag */
264 } else
265 type = 1;
266
267 /* we need to skip ahead, if there is a comment block in the main header. It causes that
268 * header tp be larger that a simple 13 byte block.
269 */
270 head_size = archive_header_block[6] << 8 | archive_header_block[5];
271 if (head_size > 13)
272 fseek(fp, head_size-13, SEEK_CUR);
273
274next_file_header:
275 /* file header block */
276 count = fread(file_header_block, 32, 1, fp);
277
278 if (feof(fp)) {
279 if (verbose) {
280 fprintf(stderr, "! %s: End of file\n", archive_name);
281 }
282 goto BailOut;
283 }
284
285 if (count != 1) {
286 fprintf(stderr, "%s: Error: read failed: %s.\n",
287 archive_name, strerror(errno));
288 goto err;
289 }
290
291 if (type == 1 && file_header_block[2] == 0x7a) {
292 if (verbose) {
293 fprintf(stderr, "! %s: Comment block present?\n", archive_name);
294 }
295 }
296 else if (type == 1 && file_header_block[2] != 0x74) {
297 fprintf(stderr, "! %s: Not recognising any more headers.\n", archive_name);
298 goto BailOut;
299 }
300
301 file_header_head_flags =
302 file_header_block[4] << 8 | file_header_block[3];
303
304 /* process -hp mode files
305 use Marc's end-of-archive block decrypt trick */
306 if (type == 0) {
307 unsigned char buf[24];
308
309 if (verbose) {
310 fprintf(stderr, "! -hp mode entry found in %s\n", base_aname);
311 }
312 printf("%s:$RAR3$*%d*", base_aname, type);
313 jtr_fseek64(fp, -24, SEEK_END);
314 if (fread(buf, 24, 1, fp) != 1) {
315 fprintf(stderr, "%s: Error: read failed: %s.\n",
316 archive_name, strerror(errno));
317 goto err;
318 }
319
320 for (i = 0; i < 8; i++) { /* salt */
321 printf("%c%c", itoa16[ARCH_INDEX(buf[i] >> 4)],
322 itoa16[ARCH_INDEX(buf[i] & 0x0f)]);
323 }
324 printf("*");
325 /* encrypted block with known plaintext */
326 for (i = 8; i < 24; i++) {
327 printf("%c%c", itoa16[ARCH_INDEX(buf[i] >> 4)],
328 itoa16[ARCH_INDEX(buf[i] & 0x0f)]);
329 }
330 printf(":%d::::%s\n", type, archive_name);
331 } else {
332 size_t file_header_pack_size = 0, file_header_unp_size = 0;
333 int ext_time_size;
334 uint64_t bytes_left;
335 uint16_t file_header_head_size, file_name_size;
336 unsigned char file_name[256], file_crc[4];
337 unsigned char salt[8] = { 0 };
338 unsigned char rejbuf[32];
339 char *p;
340 unsigned char s;
341
342 if (!(file_header_head_flags & 0x8000)) {
343 fprintf(stderr, "File header flag 0x8000 unset, bailing out.\n");
344 goto BailOut;
345 }
346
347 file_header_head_size =
348 file_header_block[6] << 8 | file_header_block[5];
349
350 /* low 32 bits. If header_flags & 0x100 set, then there are additional
351 32 bits of length data later in the header. FIXME! */
352 file_header_pack_size = file_header_block[10];
353 file_header_pack_size <<= 8; file_header_pack_size += file_header_block[9];
354 file_header_pack_size <<= 8; file_header_pack_size += file_header_block[8];
355 file_header_pack_size <<= 8; file_header_pack_size += file_header_block[7];
356
357 file_header_unp_size = file_header_block[14];
358 file_header_unp_size <<= 8; file_header_unp_size += file_header_block[13];
359 file_header_unp_size <<= 8; file_header_unp_size += file_header_block[12];
360 file_header_unp_size <<= 8; file_header_unp_size += file_header_block[11];
361
362 if (verbose) {
363 fprintf(stderr,
364 "! HEAD_SIZE: %d, PACK_SIZE: %"PRIu64", UNP_SIZE: %"PRIu64"\n",
365 file_header_head_size,
366 (uint64_t)file_header_pack_size,
367 (uint64_t)file_header_unp_size);
368 fprintf(stderr, "! file_header_block:\n! ");
369 for (i = 0; i < 32; ++i)
370 fprintf(stderr, " %02x", file_header_block[i]);
371 fprintf(stderr, "\n");
372 }
373 /* calculate EXT_TIME size */
374 ext_time_size = file_header_head_size - 32;
375
376 if (file_header_head_flags & 0x100) {
377 uint64_t ex;
378 if (fread(rejbuf, 4, 1, fp) != 1) {
379 fprintf(stderr, "\n! %s: Error: read failed: %s.\n",
380 archive_name, strerror(errno));
381 goto err;
382 }
383 if (verbose) {
384 fprintf(stderr, "! ");
385 for (i = 0; i < 4; ++i)
386 fprintf(stderr, " %02x", rejbuf[i]);
387 }
388 ex = rejbuf[3];
389 ex <<= 8; ex += rejbuf[2];
390 ex <<= 8; ex += rejbuf[1];
391 ex <<= 8; ex += rejbuf[0];
392 ex <<= 32;
393 file_header_pack_size += ex;
394 ext_time_size -= 4;
395
396 if (fread(rejbuf, 4, 1, fp) != 1) {
397 fprintf(stderr, "\n! %s: Error: read failed: %s.\n",
398 archive_name, strerror(errno));
399 goto err;
400 }
401 if (verbose) {
402 for (i = 0; i < 4; ++i)
403 fprintf(stderr, " %02x", rejbuf[i]);
404 fprintf(stderr, " (High Pack/Unp extra header data)\n");
405 }
406 ex = rejbuf[3];
407 ex <<= 8; ex += rejbuf[2];
408 ex <<= 8; ex += rejbuf[1];
409 ex <<= 8; ex += rejbuf[0];
410 ex <<= 32;
411 file_header_unp_size += ex;
412 ext_time_size -= 4;
413 if (verbose) {
414 /* note, we should warn (or bail) if sizeof(size_t) < 8) FIXME! */
415 fprintf(stderr, "! HIGH_PACK_SIZE present\n");
416 fprintf(stderr, "! HIGH_UNP_SIZE present\n");
417 }
418 } else
419 fprintf(stderr, "\n");
420 /* file name processing */
421 file_name_size =
422 file_header_block[27] << 8 | file_header_block[26];
423 if (verbose) {
424 fprintf(stderr, "! file name size: %d bytes\n", file_name_size);
425 }
426 memset(file_name, 0, sizeof(file_name));
427
428 if (!check_fread(sizeof(file_name), file_name_size, 1))
429 goto err;
430 if (fread(file_name, file_name_size, 1, fp) != 1) {
431 fprintf(stderr, "! %s: Error: read failed: %s.\n",
432 archive_name, strerror(errno));
433 goto err;
434 }
435
436 file_name[sizeof(file_name) - 1] = 0;
437 ext_time_size -= file_name_size;
438
439 /* If this flag is set, file_name contains some weird
440 wide char encoding that need to be decoded to UTF16
441 and then to UTF-8 (we don't support codepages here) */
442 if (file_header_head_flags & 0x200) {
443 UTF16 FileNameW[256];
444 int Length = strlen((char*)file_name);
445
446 if (verbose) {
447 hexdump("! Encoded filenames", file_name, file_name_size);
448 }
449 DecodeFileName(file_name, file_name + Length + 1,
450 sizeof(file_name) - Length - 1,
451 FileNameW, sizeof(FileNameW));
452
453 if (*FileNameW) {
454 if (verbose) {
455 hexdump("! UTF16 filename", FileNameW,
456 strlen16(FileNameW) << 1);
457 fprintf(stderr, "OEM name: %s\n", file_name);
458 }
459 utf16_to_utf8_r(file_name, 256, FileNameW);
460 fprintf(stderr, "! Unicode: %s\n", file_name);
461 } else
462 fprintf(stderr, "! UTF8 name: %s\n", file_name);
463 }
464 else
465 fprintf(stderr, "! file name: %s\n", file_name);
466
467 /* We duplicate file names to the GECOS field, for single mode */
468 if (gecos_len + strlen((char*)file_name) < LINE_BUFFER_SIZE)
469 gecos_len += snprintf(&gecos[gecos_len], LINE_BUFFER_SIZE - gecos_len - 1, "%s ", (char*)file_name);
470
471 /* salt processing */
472 if (file_header_head_flags & 0x400) {
473 ext_time_size -= 8;
474 if (fread(salt, 8, 1, fp) != 1) {
475 fprintf(stderr, "! %s: Error: read failed: %s.\n",
476 archive_name, strerror(errno));
477 goto err;
478 }
479
480 }
481
482 /* EXT_TIME processing */
483 if (file_header_head_flags & 0x1000) {
484 if (verbose) {
485 fprintf(stderr, "! EXT_TIME present with size %d\n",
486 ext_time_size);
487 }
488
489 if (!check_fread(sizeof(rejbuf), ext_time_size, 1))
490 goto err;
491
492 if (fread(rejbuf, ext_time_size, 1, fp) != 1) {
493 fprintf(stderr, "! %s: Error: read failed: %s.\n",
494 archive_name, strerror(errno));
495 goto err;
496 }
497 }
498
499 /* Skip solid files (first file is never solid)
500 * We could probably add support for this
501 */
502 if (file_header_head_flags & 0x10) {
503 fprintf(stderr, "! Solid, can't handle (currently)\n");
504 jtr_fseek64(fp, file_header_pack_size, SEEK_CUR);
505 goto next_file_header;
506 }
507
508 if ((file_header_head_flags & 0xe0)>>5 == 7) {
509 if (verbose) {
510 fprintf(stderr, "! Is a directory, skipping\n");
511 }
512 jtr_fseek64(fp, file_header_pack_size, SEEK_CUR);
513 goto next_file_header;
514 }
515 else if (verbose) {
516 fprintf(stderr, "! Dictionary size: %u KB\n", 64<<((file_header_head_flags & 0xe0)>>5));
517 }
518
519 /* Check if encryption is being used */
520 if (!(file_header_head_flags & 0x04)) {
521 fprintf(stderr, "! not encrypted, skipping\n");
522 jtr_fseek64(fp, file_header_pack_size, SEEK_CUR);
523 goto next_file_header;
524 }
525
526 /* Prefer shorter files, except zero-byte ones */
527 if (bestsize && (bestsize < file_header_unp_size)) {
528 jtr_fseek64(fp, file_header_pack_size, SEEK_CUR);
529 goto next_file_header;
530 }
531
532 bestsize = file_header_unp_size;
533
534 MEM_FREE(best);
535 best = mem_calloc(1, 2 * LINE_BUFFER_SIZE + 2 * file_header_pack_size);
536
537 /* process encrypted data of size "file_header_pack_size" */
538 best_len = sprintf(best, "%s:$RAR3$*%d*", base_aname, type);
539 for (i = 0; i < 8; i++) { /* encode salt */
540 best_len += sprintf(&best[best_len], "%c%c", itoa16[ARCH_INDEX(salt[i] >> 4)], itoa16[ARCH_INDEX(salt[i] & 0x0f)]);
541 }
542 if (verbose) {
543 fprintf(stderr, "! salt: '%s'\n", best);
544 }
545 best_len += sprintf(&best[best_len], "*");
546 memcpy(file_crc, file_header_block + 16, 4);
547 for (i = 0; i < 4; i++) { /* encode file_crc */
548 best_len += sprintf(&best[best_len], "%c%c", itoa16[ARCH_INDEX(file_crc[i] >> 4)], itoa16[ARCH_INDEX(file_crc[i] & 0x0f)]);
549 }
550 if (verbose) {
551 /* Minimal version needed to unpack this file */
552 fprintf(stderr, "! UNP_VER is %0.1f\n", (float)file_header_block[24] / 10.);
553 }
554 /*
555 * 0x30 - storing
556 * 0x31 - fastest compression
557 * 0x32 - fast compression
558 * 0x33 - normal compression (default)
559 * 0x34 - good compression
560 * 0x35 - best compression
561 *
562 * m3b means 0x33 and a dictionary size of 128KB (a == 64KB .. g == 4096KB)
563 */
564 if (verbose) {
565 fprintf(stderr, "! METHOD is m%x%c\n", file_header_block[25]-0x30, 'a'+((file_header_head_flags&0xe0)>>5));
566 //fprintf(stderr, "! file_header_flags is 0x%04x\n", file_header_head_flags);
567 }
568
569 best_len += sprintf(&best[best_len], "*%"PRIu64"*%"PRIu64"*",
570 (uint64_t)file_header_pack_size,
571 (uint64_t)file_header_unp_size);
572
573 /* We always store it inline */
574
575 best_len += sprintf(&best[best_len], "1*");
576 p = &best[best_len];
577 bytes_left = file_header_pack_size;
578 for (i = 0; i < file_header_pack_size; i++) {
579 unsigned char bytes[64*1024];
580 unsigned x, to_read = 64*1024;
581 if (bytes_left < 64*1024)
582 to_read = bytes_left;
583 bytes_left -= to_read;
584 if (fread(bytes, 1, to_read, fp) != to_read)
585 fprintf(stderr, "! Error while reading archive: %s\n", strerror(errno));
586 for (x = 0; x < to_read; ++x) {
587 s = bytes[x];
588 *p++ = itoa16[s >> 4];
589 *p++ = itoa16[s & 0xf];
590 }
591 }
592 best_len += file_header_pack_size;
593 best_len += sprintf(p, "*%c%c:%d::", itoa16[file_header_block[25]>>4], itoa16[file_header_block[25]&0xf], type);
594
595 /* Keep looking for better candidates */
596 goto next_file_header;
597
598BailOut:
599 if (best && *best) {
600 if (verbose) {
601 fprintf(stderr, "! Found a valid -p mode candidate in %s\n", base_aname);
602 }
603 strncat(best, gecos, LINE_BUFFER_SIZE - best_len - 1);
604 puts(best);
605 } else
606 fprintf(stderr, "! Did not find a valid encrypted candidate in %s\n", base_aname);
607 }
608
609err:
610 if (fp)
611 fclose(fp);
612 MEM_FREE(best);
613 MEM_FREE(gecos);
614}
615
616
617/**************************************************************************
618 * Here are the functions and tools for RAR5
619 *************************************************************************/
620
621// global variables
622static int Encrypted = 0;
623static unsigned char PswCheck[SIZE_PSWCHECK];
624static unsigned rar5_interations=0, UsePswCheck=0;
625static unsigned char rar5_salt[SIZE_SALT50];
626
627/**************************************************************************
628 * These 4 functions do much of the reading for rar5 files. There is a
629 * function to read a 4 byte int (in LE format), one to read a single
630 * byte, one to to read a buffer, and one that reads the variable sized
631 * numbers used in rar5 (LE format, 7 bits used per byte with high bit
632 * used to signify if there are more bytes of data or not)
633 *************************************************************************/
634int read_uint32 (FILE *fp, uint32_t *n, uint32_t *bytes_read) {
635 unsigned char Buf[4];
636 int i, shift=0;
637 *n = 0;
638 if (fread(Buf, 1, 4, fp) < 4)
639 return 0;
640 for (i = 0; i < 4; ++i) {
641 *n = *n + (Buf[i] << shift);
642 shift += 8;
643 }
644 *bytes_read += 4;
645 return 4;
646}
647int read_uint8 (FILE *fp, uint8_t *n, uint32_t *bytes_read) {
648 unsigned char Buf[1];
649 if (fread(Buf, 1, 1, fp) < 1)
650 return 0;
651 *n = Buf[0];
652 *bytes_read += 1;
653 return 1;
654}
655int read_buf (FILE *fp, unsigned char *cp, int len, uint32_t *bytes_read) {
656 if (fread(cp, 1, len, fp) < 1)
657 return 0;
658 *bytes_read += len;
659 return len;
660}
661int read_vuint (FILE *fp, uint64_t *n, uint32_t *bytes_read) {
662 unsigned char c;
663 int i, shift=0;
664 uint64_t accum;
665 *n = 0;
666 for (i = 0; i < 10; ++i) {
667 if (fread(&c, 1, 1, fp) != 1)
668 return 0;
669 accum = (c&0x7f);
670 *n = *n + (accum << shift);
671 shift += 7;
672 if ((c & 0x80) == 0) {
673 *bytes_read += i+1;
674 return i+1;
675 }
676 }
677 return 0;
678}
679
680/**************************************************************************
681 * Process an 'extra' block of data. This is where rar5 stores the
682 * encryption block.
683 *************************************************************************/
684static int ProcessExtra50(FILE *fp, uint64_t extra_size, uint64_t HeadSize, uint32_t HeaderType, uint32_t CurBlockPos, const char *archive_name) {
685 uint64_t FieldSize, FieldType, EncVersion, Flags;
686 uint32_t bytes_read=0;
687 int bytes_left=(int)extra_size;
688 unsigned char Lg2Count;
689
690 // fprintf(stderr, "in extra50 extrasize=%d\n", extra_size);
691 while (1) {
692 int len = read_vuint(fp, &FieldSize, &bytes_read);
693 if (!len || len > 3) return 0; // rar5 technote (http://www.rarlab.com/technote.htm#arcblocks) lists max size of header len is 3 byte vint.
694 bytes_left -= len;
695 bytes_left -= (uint32_t)FieldSize;
696 if (bytes_left < 0) return 0;
697 if (!read_vuint(fp, &FieldType, &bytes_read)) return 0;
698 // fprintf(stderr, "in Extra50. FieldSize=%d FieldType=%d\n", FieldSize, FieldType);
699 if (HeaderType == HEAD_FILE || HeaderType == HEAD_SERVICE) {
700 if (FieldType == FHEXTRA_CRYPT) {
701 unsigned char InitV[SIZE_INITV];
702 unsigned char Hex1[128], Hex2[128], Hex3[128];
703 if (!read_vuint(fp, &EncVersion, &bytes_read)) return 0;
704 if (!read_vuint(fp, &Flags, &bytes_read)) return 0;
705 if ( (Flags & FHEXTRA_CRYPT_PSWCHECK) == 0) {
706 fprintf(stderr, "UsePswCheck is OFF. We currently don't support such files!\n");
707 return 0;
708 }
709 if (!read_uint8(fp, &Lg2Count, &bytes_read)) return 0;
710 if (Lg2Count >= CRYPT5_KDF_LG2_COUNT_MAX) {
711 fprintf(stderr, "Lg2Count >= CRYPT5_KDF_LG2_COUNT_MAX (problem with file?)");
712 return 0;
713 }
714 if (!read_buf(fp, rar5_salt, SIZE_SALT50, &bytes_read)) return 0;
715 if (!read_buf(fp, InitV, SIZE_INITV, &bytes_read)) return 0;
716 if (!read_buf(fp, PswCheck, SIZE_PSWCHECK, &bytes_read)) return 0;
717 printf("%s:$rar5$%d$%s$%d$%s$%d$%s\n",
718 archive_name,
719 SIZE_SALT50, base64_convert_cp(rar5_salt,e_b64_raw,SIZE_SALT50,Hex1,e_b64_hex,sizeof(Hex1),0, 0),
720 Lg2Count, base64_convert_cp(InitV,e_b64_raw,SIZE_INITV,Hex2,e_b64_hex,sizeof(Hex2),0, 0),
721 SIZE_PSWCHECK, base64_convert_cp(PswCheck,e_b64_raw,SIZE_PSWCHECK,Hex3,e_b64_hex,sizeof(Hex3),0, 0));
722 return 0;
723 }
724 }
725 }
726 return 1;
727 }
728
729/**************************************************************************
730 * Common file header processing for rar5
731 *************************************************************************/
732
733static size_t read_rar5_header(FILE *fp, size_t CurBlockPos, uint8_t *HeaderType, const char *archive_name) {
734 uint64_t block_size, flags, extra_size=0, data_size=0;
735 uint64_t crypt_version, enc_flags, HeadSize;
736 uint32_t head_crc, header_bytes_read = 0, sizeof_vint;
737 uint8_t header_type, lg_2count;
738
739 if (Encrypted) {
740 // The header is encrypted, so we simply find the IV from this block.
741 unsigned char HeadersInitV[SIZE_INITV];
742 unsigned char Hex1[128], Hex2[128], Hex3[128];
743 sizeof_vint = read_buf(fp, HeadersInitV, SIZE_INITV, &header_bytes_read);
744 if (sizeof_vint != SIZE_INITV) {
745 fprintf(stderr, "Error, rar file %s too short, could not read IV from header\n", archive_name);
746 return 0;
747 }
748 printf("%s:$rar5$%d$%s$%d$%s$%d$%s\n",
749 archive_name,
750 SIZE_SALT50, base64_convert_cp(rar5_salt,e_b64_raw,SIZE_SALT50,Hex1,e_b64_hex,sizeof(Hex1),0, 0),
751 rar5_interations, base64_convert_cp(HeadersInitV,e_b64_raw,SIZE_INITV,Hex2,e_b64_hex,sizeof(Hex2),0, 0),
752 SIZE_PSWCHECK, base64_convert_cp(PswCheck,e_b64_raw,SIZE_PSWCHECK,Hex3,e_b64_hex,sizeof(Hex3),0, 0));
753 return 0;
754 }
755 if (!read_uint32(fp, &head_crc, &header_bytes_read)) return 0;
756
757 sizeof_vint = read_vuint(fp, &block_size, &header_bytes_read);
758 if (!sizeof_vint) return 0;
759 // The HeadSize is full size of this header from the start of the HeaderCRC, to the end of any 'extra-data' section.
760 HeadSize = block_size + 4 + sizeof_vint;
761
762 //if (!read_vuint(fp, &header_type, &header_bytes_read)) return 0;
763 if (!read_uint8(fp, &header_type, &header_bytes_read)) return 0;
764 if (!read_vuint(fp, &flags, &header_bytes_read)) return 0;
765 *HeaderType = header_type;
766 if ((flags & HFL_EXTRA) != 0) { if (!read_vuint(fp, &extra_size, &header_bytes_read)) return 0; }
767 if ((flags & HFL_DATA) != 0) { if (!read_vuint(fp, &data_size, &header_bytes_read)) return 0; }
768
769 // fprintf(stderr, "curpos=%d bs=%d firstreadsize=%d, sizeBytes=%d headtye=%d flags=%d \n", NowCurPos, block_size, 7, SizeBytes, header_type, flags);
770
771 if (header_type == HEAD_CRYPT) {
772 unsigned char chksum[SIZE_PSWCHECK_CSUM];
773 if (!read_vuint(fp, &crypt_version, &header_bytes_read)) return 0;
774 if (crypt_version > CRYPT_VERSION) { printf("bad rar crypt version byte\n"); return 0; }
775 if (!read_vuint(fp, &enc_flags, &header_bytes_read)) return 0;
776 UsePswCheck = (enc_flags & CHFL_CRYPT_PSWCHECK) != 0; // set global
777 if (!read_uint8(fp, &lg_2count, &header_bytes_read)) return 0;
778 if (lg_2count > CRYPT5_KDF_LG2_COUNT_MAX) { printf("rar PBKDF2 iteration count too large\n"); return 0; }
779 rar5_interations = lg_2count; // set global
780 // get salt
781 if (!read_buf(fp, rar5_salt, SIZE_SALT50, &header_bytes_read)) return 0;
782 if (UsePswCheck) {
783 unsigned char sha256ch[32];
784 SHA256_CTX ctx;
785 if (!read_buf(fp, PswCheck, SIZE_PSWCHECK, &header_bytes_read)) return 0;
786 if (!read_buf(fp, chksum, SIZE_PSWCHECK_CSUM, &header_bytes_read)) return 0;
787 SHA256_Init(&ctx);
788 SHA256_Update(&ctx, PswCheck, SIZE_PSWCHECK);
789 SHA256_Final(sha256ch, &ctx);
790 UsePswCheck = !memcmp(sha256ch, chksum, sizeof(chksum));
791 }
792 Encrypted = 1;
793 } else if (header_type == HEAD_MAIN) {
794 uint64_t ArcFlags, VolNumber=0;
795 if (!read_vuint(fp, &ArcFlags, &header_bytes_read)) return 0;
796 if ((ArcFlags & MHFL_VOLNUMBER) != 0)
797 if (!read_vuint(fp, &VolNumber, &header_bytes_read)) return 0;
798 } else if (header_type == HEAD_FILE || header_type == HEAD_SERVICE) {
799 uint64_t FileFlags, UnpSize, FileAttr;
800 uint64_t CompInfo, HostOS, NameSize;
801 uint32_t FileHashCRC32, tmp;
802
803 if (!read_vuint(fp, &FileFlags, &header_bytes_read)) return 0;
804 if (!read_vuint(fp, &UnpSize, &header_bytes_read)) return 0;
805 if (!read_vuint(fp, &FileAttr, &header_bytes_read)) return 0;
806
807 if ((FileFlags & FHFL_UTIME) != 0) {
808 if (!read_uint32(fp, &tmp, &header_bytes_read)) return 0;
809 //mtime = tmp;
810 }
811
812 if ((FileFlags & FHFL_CRC32) != 0) {
813 if (!read_uint32(fp, &FileHashCRC32, &header_bytes_read)) return 0;
814 }
815
816 if (!read_vuint(fp, &CompInfo, &header_bytes_read)) return 0;
817 if (!read_vuint(fp, &HostOS, &header_bytes_read)) return 0;
818 if (!read_vuint(fp, &NameSize, &header_bytes_read)) return 0;
819 // skip the field name.
820 jtr_fseek64(fp, NameSize, SEEK_CUR);
821 if (extra_size != 0)
822 ProcessExtra50(fp, extra_size, HeadSize, *HeaderType, CurBlockPos, archive_name);
823
824 } else if (header_type == HEAD_ENDARC) {
825 return 0;
826 }
827 return CurBlockPos+HeadSize+data_size;
828}
829
830/* handle rar5 files */
831static int process_file5(const char *archive_name) {
832 //fprintf(stderr, "! %s: Not a RAR 3.x file, try running rar5tojohn.py on me!\n", archive_name);
833 char Magic[8], buf[CHUNK_SIZE], *pos;
834 size_t count, NextBlockPos, CurBlockPos;
835 int diff, found = 0;
836 FILE *fp;
837
838 fp = fopen(archive_name, "rb");
839 if (!fp) { fprintf(stderr, "error opening file %s\n", archive_name); return 0; }
840 if (fread(Magic, 1, 8, fp) != 8) {
841 fclose(fp);
842 fprintf(stderr, "Error reading rar signature from file %s\n", archive_name);
843 return 0;
844 }
845 if (memcmp(Magic, "\x52\x61\x72\x21\x1a\x07\x01\x00", 8)) { /* handle SFX archives */
846 if (memcmp(Magic, "MZ", 2) == 0) {
847 /* jump to "Rar!" signature */
848 while (!feof(fp)) {
849 count = fread(buf, 1, CHUNK_SIZE, fp);
850 if ( (pos = (char*)memmem(buf, count, "\x52\x61\x72\x21\x1a\x07\x01\x00", 8))) {
851 diff = count - (pos - buf);
852 jtr_fseek64(fp, - diff, SEEK_CUR);
853 jtr_fseek64(fp, 8, SEEK_CUR);
854 found = 1;
855 break;
856 }
857 if (feof(fp)) //We shold examine the EOF before seek back
858 break;
859 jtr_fseek64(fp, -7, SEEK_CUR);
860 }
861 if (!found)
862 goto err;
863 }
864 }
865 while (1) {
866 uint8_t HeaderType;
867 CurBlockPos = (size_t)jtr_ftell64(fp);
868 NextBlockPos = read_rar5_header(fp, CurBlockPos, &HeaderType, archive_name);
869 if (!NextBlockPos)
870 break;
871 // fprintf(stderr, "NextBlockPos is %d Headertype=%d curblockpos=%d\n", NextBlockPos, HeaderType, CurBlockPos);
872 jtr_fseek64(fp, NextBlockPos, SEEK_SET);
873 }
874 if (fp) fclose(fp);
875 return 1;
876err:;
877 if (fp) fclose(fp);
878 return 0;
879}
880
881
882static int usage(char *name)
883{
884 fprintf(stderr,"Usage: %s <rar file(s)>\n", name);
885 return EXIT_FAILURE;
886}
887
888int rar2john(int argc, char **argv)
889{
890 int c;
891
892 /* Parse command line */
893 while ((c = getopt(argc, argv, "v")) != -1) {
894 switch (c) {
895 case 'v':
896 verbose = 1;
897 break;
898 case '?':
899 default:
900 return usage(argv[0]);
901 }
902 }
903 argc -= optind;
904 if (argc == 0)
905 return usage(argv[0]);
906 argv += optind;
907
908 while (argc--)
909 process_file(*argv++);
910
911 return EXIT_SUCCESS;
912}