1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#define MAXITER 256 * 100
#define MHASHLEN 40
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#define MIN(x,y) ((x) < (y) ? (x) : (y))
int
hash()
{
static char buf[MHASHLEN + 1];
char str[256];
int i, k, v;
char c, *bp;
size_t len;
if (!fgets(str, sizeof(str), stdin))
return EXIT_FAILURE;
len = strlen(str) -1;
if (len <= 0) return EXIT_FAILURE;
for (v = 0, i = 0; i < len; i++) v += str[i];
srand(v);
for (bp = buf, i = 0; i < MHASHLEN / 2; i++)
bp += sprintf(bp, "%02x", str[i % len] ^ (rand() % 256));
printf("%s\n", buf);
return EXIT_SUCCESS;
}
int
revhash(const char *hashstr)
{
char c, hexbuf[3] = { 0 }, *end, *buf;
int i, k, v, maxlen, sum, *hash, sublen, aftersum;
if (strlen(hashstr) % 2 != 0)
goto invalid;
/* alloc */
maxlen = strlen(hashstr) / 2;
hash = calloc(maxlen, sizeof(int));
buf = malloc(strlen(hashstr));
if (!hash) return EXIT_FAILURE;
/* convert hex to int array */
for (i = 0; i < maxlen; i++) {
memcpy(hexbuf, hashstr + 2 * i, 2);
hash[i] = strtol(hexbuf, &end, 16);
if (end && *end) goto invalid;
}
/* bruteforce srand seed */
for (i = 0; i < MAXITER; i++) {
srand(i);
/* reverse chars for given sum */
for (sum = i, k = 0; k < maxlen && sum > 0; k++) {
buf[k] = (char) hash[k] ^ (rand() % 256);
if (buf[k] < 0) break;
sum -= buf[k];
}
/* repeat if too short */
if (k && sum == 0) {
sublen = k;
for (k = sublen; k < maxlen; k++) {
buf[k] = (char) hash[k] ^ (rand() % 256);
if (buf[k] < 0 || buf[k] != buf[k % sublen]) break;
}
}
if (k < maxlen) continue;
/* output first part we know */
printf("%.*s", sublen, buf);
/* add rest of chars */
while (sum > 0) {
c = MIN(127, sum);
printf("%c", c);
sum -= c;
}
printf("\n");
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
invalid:
fprintf(stderr, "Invalid hash string!\n");
return EXIT_FAILURE;
}
int
main(int argc, const char **argv)
{
if (argc < 2) {
fprintf(stderr, "USAGE: revhash <hash>\n");
return EXIT_FAILURE;
}
if (!strcmp(argv[1], "hash"))
return hash();
else
return revhash(argv[1]);
}
|