forked from 34306/coruna_analysis
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsha256.js
More file actions
118 lines (100 loc) · 3.74 KB
/
Copy pathsha256.js
File metadata and controls
118 lines (100 loc) · 3.74 KB
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
115
116
117
118
/**
* SHA-256 Hash Implementation
* ============================
* Used by the module loader to compute SHA1-like hashes of module paths
* for cache-busting and module identification.
*
* This is a standard SHA-256 implementation embedded inline in the exploit kit.
* It's used by the async module loader (ZKvD0e/loadModuleAsync) to generate
* the filename hash: SHA256(salt + moduleId).substring(0, 40)
*
* Part of the Coruna exploit kit (group.html).
*/
/**
* Compute SHA-256 hash of input string
* @param {string} message - Input string to hash
* @returns {string} Hex-encoded SHA-256 hash
*/
function sha256(message) {
let hexResult = "";
function rightRotate(value, amount) {
return value >>> amount | value << 32 - amount;
}
const pow = Math.pow;
const maxWord = pow(2, 32);
const lengthProperty = "length";
let i, j;
const words = [];
const messageBitLength = 8 * message[lengthProperty];
// Initialize hash values (first 32 bits of fractional parts of square roots of first 8 primes)
let hash = sha256.h = sha256.h || [];
// Initialize round constants (first 32 bits of fractional parts of cube roots of first 64 primes)
const roundConstants = sha256.k = sha256.k || [];
let numPrimes = roundConstants[lengthProperty];
// Pre-compute prime-derived constants
const composites = {};
for (let prime = 2; numPrimes < 64; prime++) {
if (!composites[prime]) {
for (i = 0; i < 313; i += prime) {
composites[i] = prime;
}
hash[numPrimes] = pow(prime, 0.5) * maxWord | 0;
roundConstants[numPrimes++] = pow(prime, 1 / 3) * maxWord | 0;
}
}
// Pad message
message += "\x80";
while (message[lengthProperty] % 64 - 56) {
message += "\0";
}
// Parse message into 32-bit words
for (i = 0; i < message[lengthProperty]; i++) {
j = message.charCodeAt(i);
if (j >> 8) return; // Only supports ASCII
words[i >> 2] |= j << (3 - i) % 4 * 8;
}
// Append bit length
words[words[lengthProperty]] = messageBitLength / maxWord | 0;
words[words[lengthProperty]] = messageBitLength;
// Process each 512-bit block
for (j = 0; j < words[lengthProperty];) {
const block = words.slice(j, j += 16);
const previousHash = hash;
hash = hash.slice(0, 8);
for (i = 0; i < 64; i++) {
const w15 = block[i - 15];
const w2 = block[i - 2];
const a = hash[0];
const e = hash[4];
// Extend message schedule + compression
j = hash[7]
+ (rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25))
+ (e & hash[5] ^ ~e & hash[6])
+ roundConstants[i]
+ (block[i] = i < 16
? block[i]
: block[i - 16]
+ (rightRotate(w15, 7) ^ rightRotate(w15, 18) ^ w15 >>> 3)
+ block[i - 7]
+ (rightRotate(w2, 17) ^ rightRotate(w2, 19) ^ w2 >>> 10)
| 0);
hash = [
j + ((rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22))
+ (a & hash[1] ^ a & hash[2] ^ hash[1] & hash[2])) | 0
].concat(hash);
hash[4] = hash[4] + j | 0;
}
// Add compressed chunk to current hash value
for (i = 0; i < 8; i++) {
hash[i] = hash[i] + previousHash[i] | 0;
}
}
// Produce final hex string
for (i = 0; i < 8; i++) {
for (j = 3; j + 1; j--) {
const byte = hash[i] >> 8 * j & 255;
hexResult += (byte < 16 ? 0 : "") + byte.toString(16);
}
}
return hexResult;
}