meshcore-hashtag-cracker 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/core.d.ts +69 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +244 -0
- package/dist/core.js.map +1 -0
- package/dist/cpu-bruteforce.d.ts +13 -0
- package/dist/cpu-bruteforce.d.ts.map +1 -0
- package/dist/cpu-bruteforce.js +45 -0
- package/dist/cpu-bruteforce.js.map +1 -0
- package/dist/cracker.d.ts +64 -0
- package/dist/cracker.d.ts.map +1 -0
- package/dist/cracker.js +358 -0
- package/dist/cracker.js.map +1 -0
- package/dist/gpu-bruteforce.d.ts +34 -0
- package/dist/gpu-bruteforce.d.ts.map +1 -0
- package/dist/gpu-bruteforce.js +645 -0
- package/dist/gpu-bruteforce.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +110 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MeshCore Cracker - Standalone library for cracking MeshCore GroupText packets
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { GroupTextCracker } from 'meshcore-cracker';
|
|
7
|
+
*
|
|
8
|
+
* const cracker = new GroupTextCracker();
|
|
9
|
+
*
|
|
10
|
+
* // Optional: load wordlist for dictionary attack
|
|
11
|
+
* await cracker.loadWordlist('/words_alpha.txt');
|
|
12
|
+
*
|
|
13
|
+
* const result = await cracker.crack(packetHex, {
|
|
14
|
+
* maxLength: 6,
|
|
15
|
+
* useTimestampFilter: true,
|
|
16
|
+
* useUtf8Filter: true,
|
|
17
|
+
* }, (progress) => {
|
|
18
|
+
* console.log(`${progress.percent.toFixed(1)}% - ETA: ${progress.etaSeconds}s`);
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* if (result.found) {
|
|
22
|
+
* console.log(`Room: #${result.roomName}`);
|
|
23
|
+
* console.log(`Message: ${result.decryptedMessage}`);
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* cracker.destroy();
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export { GroupTextCracker } from './cracker';
|
|
30
|
+
export type { CrackOptions, CrackResult, ProgressReport, ProgressCallback, DecodedPacket, } from './types';
|
|
31
|
+
export { deriveKeyFromRoomName, getChannelHash, verifyMac, isTimestampValid, isValidUtf8, indexToRoomName, roomNameToIndex, countNamesForLength, PUBLIC_ROOM_NAME, PUBLIC_KEY, DEFAULT_VALID_SECONDS, } from './core';
|
|
32
|
+
export { isWebGpuSupported } from './gpu-bruteforce';
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAG7C,YAAY,EACV,YAAY,EACZ,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,aAAa,GACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,qBAAqB,GACtB,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MeshCore Cracker - Standalone library for cracking MeshCore GroupText packets
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { GroupTextCracker } from 'meshcore-cracker';
|
|
7
|
+
*
|
|
8
|
+
* const cracker = new GroupTextCracker();
|
|
9
|
+
*
|
|
10
|
+
* // Optional: load wordlist for dictionary attack
|
|
11
|
+
* await cracker.loadWordlist('/words_alpha.txt');
|
|
12
|
+
*
|
|
13
|
+
* const result = await cracker.crack(packetHex, {
|
|
14
|
+
* maxLength: 6,
|
|
15
|
+
* useTimestampFilter: true,
|
|
16
|
+
* useUtf8Filter: true,
|
|
17
|
+
* }, (progress) => {
|
|
18
|
+
* console.log(`${progress.percent.toFixed(1)}% - ETA: ${progress.etaSeconds}s`);
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* if (result.found) {
|
|
22
|
+
* console.log(`Room: #${result.roomName}`);
|
|
23
|
+
* console.log(`Message: ${result.decryptedMessage}`);
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* cracker.destroy();
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
// Main cracker class
|
|
30
|
+
export { GroupTextCracker } from './cracker';
|
|
31
|
+
// Utility exports for advanced usage
|
|
32
|
+
export { deriveKeyFromRoomName, getChannelHash, verifyMac, isTimestampValid, isValidUtf8, indexToRoomName, roomNameToIndex, countNamesForLength, PUBLIC_ROOM_NAME, PUBLIC_KEY, DEFAULT_VALID_SECONDS, } from './core';
|
|
33
|
+
export { isWebGpuSupported } from './gpu-bruteforce';
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,qBAAqB;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAW7C,qCAAqC;AACrC,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,qBAAqB,GACtB,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for configuring the cracking process.
|
|
3
|
+
*/
|
|
4
|
+
export interface CrackOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Maximum room name length to search (default: 8).
|
|
7
|
+
* Longer names exponentially increase search time.
|
|
8
|
+
*/
|
|
9
|
+
maxLength?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Minimum room name length to search (default: 1).
|
|
12
|
+
* Use this to skip shorter room names if you know the target is longer.
|
|
13
|
+
*/
|
|
14
|
+
startingLength?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Use dictionary attack before brute force (default: true).
|
|
17
|
+
* When enabled and a wordlist is loaded, tries dictionary words first.
|
|
18
|
+
* Set to false to skip dictionary attack even if a wordlist is loaded.
|
|
19
|
+
*/
|
|
20
|
+
useDictionary?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Filter results by timestamp validity (default: true).
|
|
23
|
+
* When enabled, rejects results where the decrypted timestamp
|
|
24
|
+
* is outside the validity window.
|
|
25
|
+
*/
|
|
26
|
+
useTimestampFilter?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Timestamp validity window in seconds (default: 2592000 = 30 days).
|
|
29
|
+
* Only used when useTimestampFilter is enabled.
|
|
30
|
+
* Timestamps older than this many seconds from now are rejected.
|
|
31
|
+
*/
|
|
32
|
+
validSeconds?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Filter results by UTF-8 validity (default: true).
|
|
35
|
+
* When enabled, rejects results containing invalid UTF-8 sequences.
|
|
36
|
+
*/
|
|
37
|
+
useUtf8Filter?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Resume cracking from a specific room name position.
|
|
40
|
+
* Useful for resuming interrupted searches.
|
|
41
|
+
*/
|
|
42
|
+
startFrom?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Force CPU-based cracking instead of WebGPU (default: false).
|
|
45
|
+
* Much slower but works in environments without WebGPU support.
|
|
46
|
+
* Also useful for testing.
|
|
47
|
+
*/
|
|
48
|
+
forceCpu?: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Progress information reported during cracking.
|
|
52
|
+
*/
|
|
53
|
+
export interface ProgressReport {
|
|
54
|
+
/** Total candidates checked so far */
|
|
55
|
+
checked: number;
|
|
56
|
+
/** Total candidates to check */
|
|
57
|
+
total: number;
|
|
58
|
+
/** Progress percentage (0-100) */
|
|
59
|
+
percent: number;
|
|
60
|
+
/** Current cracking rate in keys/second */
|
|
61
|
+
rateKeysPerSec: number;
|
|
62
|
+
/** Estimated time remaining in seconds */
|
|
63
|
+
etaSeconds: number;
|
|
64
|
+
/** Time elapsed since start in seconds */
|
|
65
|
+
elapsedSeconds: number;
|
|
66
|
+
/** Current room name length being tested */
|
|
67
|
+
currentLength: number;
|
|
68
|
+
/** Current room name position being tested */
|
|
69
|
+
currentPosition: string;
|
|
70
|
+
/** Current phase of cracking */
|
|
71
|
+
phase: 'public-key' | 'wordlist' | 'bruteforce';
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Callback function for progress updates.
|
|
75
|
+
* Called approximately 5 times per second during cracking.
|
|
76
|
+
*/
|
|
77
|
+
export type ProgressCallback = (report: ProgressReport) => void;
|
|
78
|
+
/**
|
|
79
|
+
* Result of a cracking operation.
|
|
80
|
+
*/
|
|
81
|
+
export interface CrackResult {
|
|
82
|
+
/** Whether a matching room name was found */
|
|
83
|
+
found: boolean;
|
|
84
|
+
/** The room name (without '#' prefix) if found */
|
|
85
|
+
roomName?: string;
|
|
86
|
+
/** The derived encryption key (hex) if found */
|
|
87
|
+
key?: string;
|
|
88
|
+
/** The decrypted message content if found */
|
|
89
|
+
decryptedMessage?: string;
|
|
90
|
+
/** Whether the operation was aborted */
|
|
91
|
+
aborted?: boolean;
|
|
92
|
+
/** Position to resume from if aborted or failed */
|
|
93
|
+
resumeFrom?: string;
|
|
94
|
+
/** Error message if an error occurred */
|
|
95
|
+
error?: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Decoded packet information extracted from a MeshCore GroupText packet.
|
|
99
|
+
*/
|
|
100
|
+
export interface DecodedPacket {
|
|
101
|
+
/** Channel hash (1 byte, hex) */
|
|
102
|
+
channelHash: string;
|
|
103
|
+
/** Encrypted ciphertext (hex) */
|
|
104
|
+
ciphertext: string;
|
|
105
|
+
/** MAC for verification (2 bytes, hex) */
|
|
106
|
+
cipherMac: string;
|
|
107
|
+
/** Whether this is a GroupText packet */
|
|
108
|
+
isGroupText: boolean;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAEhB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IAEd,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAEhB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC;IAEvB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IAEnB,0CAA0C;IAC1C,cAAc,EAAE,MAAM,CAAC;IAEvB,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IAEtB,8CAA8C;IAC9C,eAAe,EAAE,MAAM,CAAC;IAExB,gCAAgC;IAChC,KAAK,EAAE,YAAY,GAAG,UAAU,GAAG,YAAY,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,KAAK,EAAE,OAAO,CAAC;IAEf,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,6CAA6C;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IAEpB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IAEnB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAElB,yCAAyC;IACzC,WAAW,EAAE,OAAO,CAAC;CACtB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "meshcore-hashtag-cracker",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MeshCore hashtag Grouptext packet brute-forcer",
|
|
5
|
+
"author": "Jack Kingsman",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/jkingsman/meshcore-hashtag-cracker.git"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/jkingsman/meshcore-hashtag-cracker#readme",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/jkingsman/meshcore-hashtag-cracker/issues"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsc",
|
|
31
|
+
"watch": "tsc --watch",
|
|
32
|
+
"test": "vitest run",
|
|
33
|
+
"test:watch": "vitest",
|
|
34
|
+
"prepublishOnly": "npm run build && npm test"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@michaelhart/meshcore-decoder": "^0.2.7",
|
|
38
|
+
"crypto-js": "^4.2.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/crypto-js": "^4.2.2",
|
|
42
|
+
"@webgpu/types": "^0.1.68",
|
|
43
|
+
"typescript": "^5.7.2",
|
|
44
|
+
"vitest": "^4.0.16"
|
|
45
|
+
},
|
|
46
|
+
"keywords": [
|
|
47
|
+
"meshcore",
|
|
48
|
+
"cracker",
|
|
49
|
+
"brute-force",
|
|
50
|
+
"webgpu"
|
|
51
|
+
],
|
|
52
|
+
"directories": {
|
|
53
|
+
"test": "test"
|
|
54
|
+
}
|
|
55
|
+
}
|