cyberchef 9.37.2 → 9.38.1
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/CHANGELOG.md +7 -2
- package/Gruntfile.js +2 -1
- package/package.json +4 -2
- package/src/core/config/Categories.json +1 -0
- package/src/core/config/OperationConfig.json +106 -3
- package/src/core/config/modules/Default.mjs +2 -0
- package/src/core/config/scripts/newMinorVersion.mjs +144 -0
- package/src/core/lib/Binary.mjs +9 -5
- package/src/core/lib/Extract.mjs +16 -11
- package/src/core/lib/FileSignatures.mjs +12 -12
- package/src/core/lib/Protocol.mjs +47 -0
- package/src/core/lib/Sort.mjs +105 -0
- package/src/core/lib/Stream.mjs +22 -12
- package/src/core/operations/ExtractDates.mjs +7 -1
- package/src/core/operations/ExtractDomains.mjs +29 -5
- package/src/core/operations/ExtractEmailAddresses.mjs +29 -5
- package/src/core/operations/ExtractFilePaths.mjs +38 -14
- package/src/core/operations/ExtractIPAddresses.mjs +44 -27
- package/src/core/operations/ExtractMACAddresses.mjs +28 -6
- package/src/core/operations/ExtractURLs.mjs +28 -5
- package/src/core/operations/ParseTCP.mjs +245 -0
- package/src/core/operations/ParseUDP.mjs +29 -24
- package/src/core/operations/Sort.mjs +5 -105
- package/src/core/operations/Strings.mjs +36 -14
- package/src/core/operations/ToBase45.mjs +4 -0
- package/src/core/operations/ToHex.mjs +2 -2
- package/src/core/operations/Unique.mjs +25 -5
- package/src/core/operations/index.mjs +2 -0
- package/src/node/index.mjs +5 -0
- package/src/web/App.mjs +10 -5
- package/src/web/html/index.html +12 -10
- package/src/web/stylesheets/components/_pane.css +11 -4
- package/src/web/stylesheets/layout/_controls.css +4 -0
- package/src/web/stylesheets/layout/_io.css +1 -2
- package/src/web/stylesheets/layout/_structure.css +2 -2
- package/src/web/waiters/OperationsWaiter.mjs +5 -1
- package/src/web/waiters/OutputWaiter.mjs +2 -0
- package/src/web/waiters/WindowWaiter.mjs +2 -2
- package/tests/node/tests/operations.mjs +3 -4
- package/tests/operations/index.mjs +1 -0
- package/tests/operations/tests/ExtractEmailAddresses.mjs +4 -4
- package/tests/operations/tests/ParseTCP.mjs +44 -0
- package/tests/operations/tests/ParseUDP.mjs +5 -18
- package/webpack.config.js +11 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sorting functions
|
|
3
|
+
*
|
|
4
|
+
* @author n1474335 [n1474335@gmail.com]
|
|
5
|
+
* @copyright Crown Copyright 2022
|
|
6
|
+
* @license Apache-2.0
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Comparison operation for sorting of strings ignoring case.
|
|
12
|
+
*
|
|
13
|
+
* @param {string} a
|
|
14
|
+
* @param {string} b
|
|
15
|
+
* @returns {number}
|
|
16
|
+
*/
|
|
17
|
+
export function caseInsensitiveSort(a, b) {
|
|
18
|
+
return a.toLowerCase().localeCompare(b.toLowerCase());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Comparison operation for sorting of IPv4 addresses.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} a
|
|
26
|
+
* @param {string} b
|
|
27
|
+
* @returns {number}
|
|
28
|
+
*/
|
|
29
|
+
export function ipSort(a, b) {
|
|
30
|
+
let a_ = a.split("."),
|
|
31
|
+
b_ = b.split(".");
|
|
32
|
+
|
|
33
|
+
a_ = a_[0] * 0x1000000 + a_[1] * 0x10000 + a_[2] * 0x100 + a_[3] * 1;
|
|
34
|
+
b_ = b_[0] * 0x1000000 + b_[1] * 0x10000 + b_[2] * 0x100 + b_[3] * 1;
|
|
35
|
+
|
|
36
|
+
if (isNaN(a_) && !isNaN(b_)) return 1;
|
|
37
|
+
if (!isNaN(a_) && isNaN(b_)) return -1;
|
|
38
|
+
if (isNaN(a_) && isNaN(b_)) return a.localeCompare(b);
|
|
39
|
+
|
|
40
|
+
return a_ - b_;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Comparison operation for sorting of numeric values.
|
|
45
|
+
*
|
|
46
|
+
* @author Chris van Marle
|
|
47
|
+
* @param {string} a
|
|
48
|
+
* @param {string} b
|
|
49
|
+
* @returns {number}
|
|
50
|
+
*/
|
|
51
|
+
export function numericSort(a, b) {
|
|
52
|
+
const a_ = a.split(/([^\d]+)/),
|
|
53
|
+
b_ = b.split(/([^\d]+)/);
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < a_.length && i < b.length; ++i) {
|
|
56
|
+
if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers
|
|
57
|
+
if (!isNaN(a_[i]) && isNaN(b_[i])) return -1;
|
|
58
|
+
if (isNaN(a_[i]) && isNaN(b_[i])) {
|
|
59
|
+
const ret = a_[i].localeCompare(b_[i]); // Compare strings
|
|
60
|
+
if (ret !== 0) return ret;
|
|
61
|
+
}
|
|
62
|
+
if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers
|
|
63
|
+
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return a.localeCompare(b);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Comparison operation for sorting of hexadecimal values.
|
|
72
|
+
*
|
|
73
|
+
* @author Chris van Marle
|
|
74
|
+
* @param {string} a
|
|
75
|
+
* @param {string} b
|
|
76
|
+
* @returns {number}
|
|
77
|
+
*/
|
|
78
|
+
export function hexadecimalSort(a, b) {
|
|
79
|
+
let a_ = a.split(/([^\da-f]+)/i),
|
|
80
|
+
b_ = b.split(/([^\da-f]+)/i);
|
|
81
|
+
|
|
82
|
+
a_ = a_.map(v => {
|
|
83
|
+
const t = parseInt(v, 16);
|
|
84
|
+
return isNaN(t) ? v : t;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
b_ = b_.map(v => {
|
|
88
|
+
const t = parseInt(v, 16);
|
|
89
|
+
return isNaN(t) ? v : t;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
for (let i = 0; i < a_.length && i < b.length; ++i) {
|
|
93
|
+
if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers
|
|
94
|
+
if (!isNaN(a_[i]) && isNaN(b_[i])) return -1;
|
|
95
|
+
if (isNaN(a_[i]) && isNaN(b_[i])) {
|
|
96
|
+
const ret = a_[i].localeCompare(b_[i]); // Compare strings
|
|
97
|
+
if (ret !== 0) return ret;
|
|
98
|
+
}
|
|
99
|
+
if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers
|
|
100
|
+
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return a.localeCompare(b);
|
|
105
|
+
}
|
package/src/core/lib/Stream.mjs
CHANGED
|
@@ -27,15 +27,17 @@ export default class Stream {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
* Get a number of bytes from the current position.
|
|
30
|
+
* Get a number of bytes from the current position, or all remaining bytes.
|
|
31
31
|
*
|
|
32
|
-
* @param {number} numBytes
|
|
32
|
+
* @param {number} [numBytes=null]
|
|
33
33
|
* @returns {Uint8Array}
|
|
34
34
|
*/
|
|
35
|
-
getBytes(numBytes) {
|
|
35
|
+
getBytes(numBytes=null) {
|
|
36
36
|
if (this.position > this.length) return undefined;
|
|
37
37
|
|
|
38
|
-
const newPosition =
|
|
38
|
+
const newPosition = numBytes !== null ?
|
|
39
|
+
this.position + numBytes :
|
|
40
|
+
this.length;
|
|
39
41
|
const bytes = this.bytes.slice(this.position, newPosition);
|
|
40
42
|
this.position = newPosition;
|
|
41
43
|
this.bitPos = 0;
|
|
@@ -91,34 +93,40 @@ export default class Stream {
|
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
/**
|
|
94
|
-
* Reads a number of bits from the buffer.
|
|
95
|
-
*
|
|
96
|
-
* @TODO Add endianness
|
|
96
|
+
* Reads a number of bits from the buffer in big or little endian.
|
|
97
97
|
*
|
|
98
98
|
* @param {number} numBits
|
|
99
|
+
* @param {string} [endianness="be"]
|
|
99
100
|
* @returns {number}
|
|
100
101
|
*/
|
|
101
|
-
readBits(numBits) {
|
|
102
|
+
readBits(numBits, endianness="be") {
|
|
102
103
|
if (this.position > this.length) return undefined;
|
|
103
104
|
|
|
104
105
|
let bitBuf = 0,
|
|
105
106
|
bitBufLen = 0;
|
|
106
107
|
|
|
107
108
|
// Add remaining bits from current byte
|
|
108
|
-
bitBuf =
|
|
109
|
+
bitBuf = this.bytes[this.position++] & bitMask(this.bitPos);
|
|
110
|
+
if (endianness !== "be") bitBuf >>>= this.bitPos;
|
|
109
111
|
bitBufLen = 8 - this.bitPos;
|
|
110
112
|
this.bitPos = 0;
|
|
111
113
|
|
|
112
114
|
// Not enough bits yet
|
|
113
115
|
while (bitBufLen < numBits) {
|
|
114
|
-
|
|
116
|
+
if (endianness === "be")
|
|
117
|
+
bitBuf = (bitBuf << bitBufLen) | this.bytes[this.position++];
|
|
118
|
+
else
|
|
119
|
+
bitBuf |= this.bytes[this.position++] << bitBufLen;
|
|
115
120
|
bitBufLen += 8;
|
|
116
121
|
}
|
|
117
122
|
|
|
118
123
|
// Reverse back to numBits
|
|
119
124
|
if (bitBufLen > numBits) {
|
|
120
125
|
const excess = bitBufLen - numBits;
|
|
121
|
-
|
|
126
|
+
if (endianness === "be")
|
|
127
|
+
bitBuf >>>= excess;
|
|
128
|
+
else
|
|
129
|
+
bitBuf &= (1 << numBits) - 1;
|
|
122
130
|
bitBufLen -= excess;
|
|
123
131
|
this.position--;
|
|
124
132
|
this.bitPos = 8 - excess;
|
|
@@ -133,7 +141,9 @@ export default class Stream {
|
|
|
133
141
|
* @returns {number} The bit mask
|
|
134
142
|
*/
|
|
135
143
|
function bitMask(bitPos) {
|
|
136
|
-
return
|
|
144
|
+
return endianness === "be" ?
|
|
145
|
+
(1 << (8 - bitPos)) - 1 :
|
|
146
|
+
256 - (1 << bitPos);
|
|
137
147
|
}
|
|
138
148
|
}
|
|
139
149
|
|
|
@@ -44,7 +44,13 @@ class ExtractDates extends Operation {
|
|
|
44
44
|
date3 = "(?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])[- /.](?:19|20)\\d\\d", // mm/dd/yyyy
|
|
45
45
|
regex = new RegExp(date1 + "|" + date2 + "|" + date3, "ig");
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
const results = search(input, regex);
|
|
48
|
+
|
|
49
|
+
if (displayTotal) {
|
|
50
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
51
|
+
} else {
|
|
52
|
+
return results.join("\n");
|
|
53
|
+
}
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search, DOMAIN_REGEX } from "../lib/Extract.mjs";
|
|
9
|
+
import { caseInsensitiveSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract domains operation
|
|
@@ -25,9 +26,19 @@ class ExtractDomains extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "Display total",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: false
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "Sort",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: false
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Unique",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
31
42
|
}
|
|
32
43
|
];
|
|
33
44
|
}
|
|
@@ -38,8 +49,21 @@ class ExtractDomains extends Operation {
|
|
|
38
49
|
* @returns {string}
|
|
39
50
|
*/
|
|
40
51
|
run(input, args) {
|
|
41
|
-
const displayTotal = args
|
|
42
|
-
|
|
52
|
+
const [displayTotal, sort, unique] = args;
|
|
53
|
+
|
|
54
|
+
const results = search(
|
|
55
|
+
input,
|
|
56
|
+
DOMAIN_REGEX,
|
|
57
|
+
null,
|
|
58
|
+
sort ? caseInsensitiveSort : null,
|
|
59
|
+
unique
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
if (displayTotal) {
|
|
63
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
64
|
+
} else {
|
|
65
|
+
return results.join("\n");
|
|
66
|
+
}
|
|
43
67
|
}
|
|
44
68
|
|
|
45
69
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search } from "../lib/Extract.mjs";
|
|
9
|
+
import { caseInsensitiveSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract email addresses operation
|
|
@@ -25,9 +26,19 @@ class ExtractEmailAddresses extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "Display total",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: false
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "Sort",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: false
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Unique",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
31
42
|
}
|
|
32
43
|
];
|
|
33
44
|
}
|
|
@@ -38,10 +49,23 @@ class ExtractEmailAddresses extends Operation {
|
|
|
38
49
|
* @returns {string}
|
|
39
50
|
*/
|
|
40
51
|
run(input, args) {
|
|
41
|
-
const displayTotal = args
|
|
52
|
+
const [displayTotal, sort, unique] = args,
|
|
42
53
|
// email regex from: https://www.regextester.com/98066
|
|
43
54
|
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}\])/ig;
|
|
44
|
-
|
|
55
|
+
|
|
56
|
+
const results = search(
|
|
57
|
+
input,
|
|
58
|
+
regex,
|
|
59
|
+
null,
|
|
60
|
+
sort ? caseInsensitiveSort : null,
|
|
61
|
+
unique
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
if (displayTotal) {
|
|
65
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
66
|
+
} else {
|
|
67
|
+
return results.join("\n");
|
|
68
|
+
}
|
|
45
69
|
}
|
|
46
70
|
|
|
47
71
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search } from "../lib/Extract.mjs";
|
|
9
|
+
import { caseInsensitiveSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract file paths operation
|
|
@@ -25,19 +26,29 @@ class ExtractFilePaths extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "Windows",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: true
|
|
31
32
|
},
|
|
32
33
|
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
name: "UNIX",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: true
|
|
36
37
|
},
|
|
37
38
|
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
name: "Display total",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "Sort",
|
|
45
|
+
type: "boolean",
|
|
46
|
+
value: false
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "Unique",
|
|
50
|
+
type: "boolean",
|
|
51
|
+
value: false
|
|
41
52
|
}
|
|
42
53
|
];
|
|
43
54
|
}
|
|
@@ -48,7 +59,7 @@ class ExtractFilePaths extends Operation {
|
|
|
48
59
|
* @returns {string}
|
|
49
60
|
*/
|
|
50
61
|
run(input, args) {
|
|
51
|
-
const [includeWinPath, includeUnixPath, displayTotal] = args,
|
|
62
|
+
const [includeWinPath, includeUnixPath, displayTotal, sort, unique] = args,
|
|
52
63
|
winDrive = "[A-Z]:\\\\",
|
|
53
64
|
winName = "[A-Z\\d][A-Z\\d\\- '_\\(\\)~]{0,61}",
|
|
54
65
|
winExt = "[A-Z\\d]{1,6}",
|
|
@@ -65,12 +76,25 @@ class ExtractFilePaths extends Operation {
|
|
|
65
76
|
filePaths = unixPath;
|
|
66
77
|
}
|
|
67
78
|
|
|
68
|
-
if (filePaths) {
|
|
69
|
-
const regex = new RegExp(filePaths, "ig");
|
|
70
|
-
return search(input, regex, null, displayTotal);
|
|
71
|
-
} else {
|
|
79
|
+
if (!filePaths) {
|
|
72
80
|
return "";
|
|
73
81
|
}
|
|
82
|
+
|
|
83
|
+
const regex = new RegExp(filePaths, "ig");
|
|
84
|
+
const results = search(
|
|
85
|
+
input,
|
|
86
|
+
regex,
|
|
87
|
+
null,
|
|
88
|
+
sort ? caseInsensitiveSort : null,
|
|
89
|
+
unique
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
if (displayTotal) {
|
|
93
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
94
|
+
} else {
|
|
95
|
+
return results.join("\n");
|
|
96
|
+
}
|
|
97
|
+
|
|
74
98
|
}
|
|
75
99
|
|
|
76
100
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search } from "../lib/Extract.mjs";
|
|
9
|
+
import { ipSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract IP addresses operation
|
|
@@ -25,24 +26,34 @@ class ExtractIPAddresses extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "IPv4",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: true
|
|
31
32
|
},
|
|
32
33
|
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
name: "IPv6",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: false
|
|
36
37
|
},
|
|
37
38
|
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
name: "Remove local IPv4 addresses",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
41
42
|
},
|
|
42
43
|
{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
name: "Display total",
|
|
45
|
+
type: "boolean",
|
|
46
|
+
value: false
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "Sort",
|
|
50
|
+
type: "boolean",
|
|
51
|
+
value: false
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "Unique",
|
|
55
|
+
type: "boolean",
|
|
56
|
+
value: false
|
|
46
57
|
}
|
|
47
58
|
];
|
|
48
59
|
}
|
|
@@ -53,7 +64,7 @@ class ExtractIPAddresses extends Operation {
|
|
|
53
64
|
* @returns {string}
|
|
54
65
|
*/
|
|
55
66
|
run(input, args) {
|
|
56
|
-
const [includeIpv4, includeIpv6, removeLocal, displayTotal] = args,
|
|
67
|
+
const [includeIpv4, includeIpv6, removeLocal, displayTotal, sort, unique] = args,
|
|
57
68
|
ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?",
|
|
58
69
|
ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})((([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})";
|
|
59
70
|
let ips = "";
|
|
@@ -66,23 +77,29 @@ class ExtractIPAddresses extends Operation {
|
|
|
66
77
|
ips = ipv6;
|
|
67
78
|
}
|
|
68
79
|
|
|
69
|
-
if (ips)
|
|
70
|
-
const regex = new RegExp(ips, "ig");
|
|
80
|
+
if (!ips) return "";
|
|
71
81
|
|
|
72
|
-
|
|
73
|
-
const ten = "10\\..+",
|
|
74
|
-
oneninetwo = "192\\.168\\..+",
|
|
75
|
-
oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+",
|
|
76
|
-
onetwoseven = "127\\..+",
|
|
77
|
-
removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo +
|
|
78
|
-
"|" + oneseventwo + "|" + onetwoseven + ")");
|
|
82
|
+
const regex = new RegExp(ips, "ig");
|
|
79
83
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
const ten = "10\\..+",
|
|
85
|
+
oneninetwo = "192\\.168\\..+",
|
|
86
|
+
oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+",
|
|
87
|
+
onetwoseven = "127\\..+",
|
|
88
|
+
removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo +
|
|
89
|
+
"|" + oneseventwo + "|" + onetwoseven + ")");
|
|
90
|
+
|
|
91
|
+
const results = search(
|
|
92
|
+
input,
|
|
93
|
+
regex,
|
|
94
|
+
removeLocal ? removeRegex : null,
|
|
95
|
+
sort ? ipSort : null,
|
|
96
|
+
unique
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
if (displayTotal) {
|
|
100
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
84
101
|
} else {
|
|
85
|
-
return "";
|
|
102
|
+
return results.join("\n");
|
|
86
103
|
}
|
|
87
104
|
}
|
|
88
105
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search } from "../lib/Extract.mjs";
|
|
9
|
+
import { hexadecimalSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract MAC addresses operation
|
|
@@ -25,9 +26,19 @@ class ExtractMACAddresses extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "Display total",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: false
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "Sort",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: false
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Unique",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
31
42
|
}
|
|
32
43
|
];
|
|
33
44
|
}
|
|
@@ -38,10 +49,21 @@ class ExtractMACAddresses extends Operation {
|
|
|
38
49
|
* @returns {string}
|
|
39
50
|
*/
|
|
40
51
|
run(input, args) {
|
|
41
|
-
const displayTotal = args
|
|
42
|
-
regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig
|
|
52
|
+
const [displayTotal, sort, unique] = args,
|
|
53
|
+
regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig,
|
|
54
|
+
results = search(
|
|
55
|
+
input,
|
|
56
|
+
regex,
|
|
57
|
+
null,
|
|
58
|
+
sort ? hexadecimalSort : null,
|
|
59
|
+
unique
|
|
60
|
+
);
|
|
43
61
|
|
|
44
|
-
|
|
62
|
+
if (displayTotal) {
|
|
63
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
64
|
+
} else {
|
|
65
|
+
return results.join("\n");
|
|
66
|
+
}
|
|
45
67
|
}
|
|
46
68
|
|
|
47
69
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search, URL_REGEX } from "../lib/Extract.mjs";
|
|
9
|
+
import { caseInsensitiveSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract URLs operation
|
|
@@ -25,9 +26,19 @@ class ExtractURLs extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "Display total",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: false
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "Sort",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: false
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Unique",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
31
42
|
}
|
|
32
43
|
];
|
|
33
44
|
}
|
|
@@ -38,8 +49,20 @@ class ExtractURLs extends Operation {
|
|
|
38
49
|
* @returns {string}
|
|
39
50
|
*/
|
|
40
51
|
run(input, args) {
|
|
41
|
-
const displayTotal = args
|
|
42
|
-
|
|
52
|
+
const [displayTotal, sort, unique] = args;
|
|
53
|
+
const results = search(
|
|
54
|
+
input,
|
|
55
|
+
URL_REGEX,
|
|
56
|
+
null,
|
|
57
|
+
sort ? caseInsensitiveSort : null,
|
|
58
|
+
unique
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
if (displayTotal) {
|
|
62
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
63
|
+
} else {
|
|
64
|
+
return results.join("\n");
|
|
65
|
+
}
|
|
43
66
|
}
|
|
44
67
|
|
|
45
68
|
}
|