Merge 9afca78c9d6abe07e7fbd001fd92a1b7b1d4f54f into 4290ea753912378913b1f3f54e0fc5720afeda5d
This commit is contained in:
commit
93437be058
@ -165,6 +165,7 @@
|
|||||||
"Derive PBKDF2 key",
|
"Derive PBKDF2 key",
|
||||||
"Derive EVP key",
|
"Derive EVP key",
|
||||||
"Derive HKDF key",
|
"Derive HKDF key",
|
||||||
|
"Generate Kerberos Keytab",
|
||||||
"Bcrypt",
|
"Bcrypt",
|
||||||
"Scrypt",
|
"Scrypt",
|
||||||
"JWT Sign",
|
"JWT Sign",
|
||||||
|
|||||||
381
src/core/operations/GenerateKerberosKeytab.mjs
Normal file
381
src/core/operations/GenerateKerberosKeytab.mjs
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
/**
|
||||||
|
* @author mansiverma897993
|
||||||
|
* @copyright Crown Copyright 2026
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
import Utils from "../Utils.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize a single keytab entry into a binary Uint8Array.
|
||||||
|
*
|
||||||
|
* @param {string} principal
|
||||||
|
* @param {string} realm
|
||||||
|
* @param {number} kvno
|
||||||
|
* @param {number} etype
|
||||||
|
* @param {Uint8Array} keyBytes
|
||||||
|
* @returns {Uint8Array}
|
||||||
|
*/
|
||||||
|
function serializeEntry(principal, realm, kvno, etype, keyBytes) {
|
||||||
|
const components = principal.split("/").map(c => c.trim()).filter(Boolean);
|
||||||
|
const realmBytes = new TextEncoder().encode(realm.trim().toUpperCase());
|
||||||
|
|
||||||
|
let componentsSize = 0;
|
||||||
|
const componentsBytes = components.map(c => {
|
||||||
|
const bytes = new TextEncoder().encode(c);
|
||||||
|
componentsSize += 2 + bytes.length;
|
||||||
|
return bytes;
|
||||||
|
});
|
||||||
|
|
||||||
|
const nameType = 1; // KRB5_NT_PRINCIPAL
|
||||||
|
const timestamp = 0; // Fixed to 0 for deterministic testing
|
||||||
|
const vno8 = kvno & 0xff;
|
||||||
|
|
||||||
|
// Entry content size:
|
||||||
|
// num_components (2)
|
||||||
|
// realm len (2) + realmBytes.length
|
||||||
|
// componentsSize (each comp: 2 len + data)
|
||||||
|
// name_type (4)
|
||||||
|
// timestamp (4)
|
||||||
|
// vno8 (1)
|
||||||
|
// keyblock: keytype (2) + keylen (2) + keyBytes.length
|
||||||
|
// vno (4)
|
||||||
|
const entrySize = 2 + 2 + realmBytes.length + componentsSize + 4 + 4 + 1 + 2 + 2 + keyBytes.length + 4;
|
||||||
|
|
||||||
|
const buffer = new Uint8Array(4 + entrySize);
|
||||||
|
const view = new DataView(buffer.buffer);
|
||||||
|
|
||||||
|
let offset = 0;
|
||||||
|
|
||||||
|
// 1. size (4 bytes, signed 32-bit big-endian)
|
||||||
|
view.setInt32(offset, entrySize, false);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
// 2. num_components (2 bytes, big-endian)
|
||||||
|
view.setInt16(offset, components.length, false);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
// 3. realm length (2 bytes, big-endian)
|
||||||
|
view.setUint16(offset, realmBytes.length, false);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
// 4. realm data
|
||||||
|
buffer.set(realmBytes, offset);
|
||||||
|
offset += realmBytes.length;
|
||||||
|
|
||||||
|
// 5. components
|
||||||
|
for (const compBytes of componentsBytes) {
|
||||||
|
view.setUint16(offset, compBytes.length, false);
|
||||||
|
offset += 2;
|
||||||
|
buffer.set(compBytes, offset);
|
||||||
|
offset += compBytes.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. name_type (4 bytes, big-endian)
|
||||||
|
view.setUint32(offset, nameType, false);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
// 7. timestamp (4 bytes, big-endian)
|
||||||
|
view.setUint32(offset, timestamp, false);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
// 8. vno8 (1 byte)
|
||||||
|
view.setUint8(offset, vno8);
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
// 9. keytype (2 bytes, big-endian)
|
||||||
|
view.setUint16(offset, etype, false);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
// 10. keylen (2 bytes, big-endian)
|
||||||
|
view.setUint16(offset, keyBytes.length, false);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
// 11. key data
|
||||||
|
buffer.set(keyBytes, offset);
|
||||||
|
offset += keyBytes.length;
|
||||||
|
|
||||||
|
// 12. vno (4 bytes, big-endian)
|
||||||
|
view.setUint32(offset, kvno, false);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Kerberos Keytab operation
|
||||||
|
*/
|
||||||
|
class GenerateKerberosKeytab extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GenerateKerberosKeytab constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Generate Kerberos Keytab";
|
||||||
|
this.module = "Crypto";
|
||||||
|
this.description = "Generates a Wireshark-compatible Kerberos (KRB5) keytab file from user-provided principal keys or NT hashes. The input can be a single key in the arguments or a list of keys in the main input (in CSV/lines or JSON format).<br><br><b>Input formats:</b><br>- CSV/lines: <code>principal,realm,kvno,etype,key</code> (one per line). Supports shorter forms like <code>principal,key</code> or <code>principal,realm,key</code>.<br>- JSON: an array of keytab entry objects, e.g. <code>[{\"principal\": \"eshellstrop\", \"realm\": \"WORKGROUP\", \"kvno\": 1, \"etype\": 23, \"key\": \"hex_key\"}]</code>.<br><br><b>Supported encryption types:</b><br>- RC4-HMAC / 23 (16-byte key / 32 hex characters)<br>- AES128-CTS-HMAC-SHA1-96 / 17 (16-byte key / 32 hex characters)<br>- AES256-CTS-HMAC-SHA1-96 / 18 (32-byte key / 64 hex characters)";
|
||||||
|
this.infoURL = "https://web.mit.edu/kerberos/krb5-latest/doc/basic/keytab_def.html";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "byteArray";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Principal",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Realm",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "KVNO",
|
||||||
|
"type": "number",
|
||||||
|
"value": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Encryption Type",
|
||||||
|
"type": "option",
|
||||||
|
"value": [
|
||||||
|
"RC4-HMAC (23)",
|
||||||
|
"AES128-CTS-HMAC-SHA1-96 (17)",
|
||||||
|
"AES256-CTS-HMAC-SHA1-96 (18)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Key / NT Hash (Hex)",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Output Format",
|
||||||
|
"type": "option",
|
||||||
|
"value": [
|
||||||
|
"Raw Keytab File",
|
||||||
|
"Hex",
|
||||||
|
"Base64",
|
||||||
|
"Detailed Summary Text"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {byteArray}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const entries = [];
|
||||||
|
|
||||||
|
// 1. Try parsing main input first
|
||||||
|
if (input && input.trim()) {
|
||||||
|
let parsedJson = null;
|
||||||
|
try {
|
||||||
|
const trimmed = input.trim();
|
||||||
|
if (trimmed.startsWith("[") || trimmed.startsWith("{")) {
|
||||||
|
parsedJson = JSON.parse(trimmed);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Not valid JSON, fallback to CSV/lines
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsedJson) {
|
||||||
|
const list = Array.isArray(parsedJson) ? parsedJson : [parsedJson];
|
||||||
|
for (const item of list) {
|
||||||
|
if (typeof item === "object" && item !== null) {
|
||||||
|
const principal = item.principal || item.username || "";
|
||||||
|
const realm = item.realm || "";
|
||||||
|
const kvno = item.kvno !== undefined ? item.kvno : 1;
|
||||||
|
const etypeInput = item.etype || item.encryption_type || 23;
|
||||||
|
const key = item.key || item.nt_hash || item.value || "";
|
||||||
|
|
||||||
|
if (principal && key) {
|
||||||
|
entries.push({ principal, realm, kvno, etypeInput, key });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const rows = Utils.parseCSV(input.trim());
|
||||||
|
for (const row of rows) {
|
||||||
|
if (row.length === 0) continue;
|
||||||
|
|
||||||
|
const firstCol = row[0].trim();
|
||||||
|
if (firstCol.startsWith("#") || firstCol === "") continue;
|
||||||
|
|
||||||
|
// Ignore header line
|
||||||
|
const col1Lower = firstCol.toLowerCase();
|
||||||
|
if (col1Lower === "principal" || col1Lower === "username") continue;
|
||||||
|
|
||||||
|
if (row.length < 2) continue;
|
||||||
|
|
||||||
|
let principal = "";
|
||||||
|
let realm = "";
|
||||||
|
let kvno = 1;
|
||||||
|
let etypeInput = 23;
|
||||||
|
let key = "";
|
||||||
|
|
||||||
|
if (row.length === 2) {
|
||||||
|
principal = row[0];
|
||||||
|
key = row[1];
|
||||||
|
} else if (row.length === 3) {
|
||||||
|
principal = row[0];
|
||||||
|
realm = row[1];
|
||||||
|
key = row[2];
|
||||||
|
} else if (row.length === 4) {
|
||||||
|
principal = row[0];
|
||||||
|
realm = row[1];
|
||||||
|
const val = parseInt(row[2].trim(), 10);
|
||||||
|
if (isNaN(val)) {
|
||||||
|
etypeInput = row[2];
|
||||||
|
} else if (val === 23 || val === 17 || val === 18) {
|
||||||
|
etypeInput = val;
|
||||||
|
} else {
|
||||||
|
kvno = val;
|
||||||
|
}
|
||||||
|
key = row[3];
|
||||||
|
} else {
|
||||||
|
principal = row[0];
|
||||||
|
realm = row[1];
|
||||||
|
kvno = parseInt(row[2].trim(), 10) || 1;
|
||||||
|
etypeInput = row[3];
|
||||||
|
key = row[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (principal && key) {
|
||||||
|
entries.push({ principal, realm, kvno, etypeInput, key });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Fall back to UI args if no entries found in main input
|
||||||
|
if (entries.length === 0) {
|
||||||
|
const principal = args[0] || "";
|
||||||
|
const realm = args[1] || "";
|
||||||
|
const kvno = args[2] !== undefined ? args[2] : 1;
|
||||||
|
const etypeInput = args[3];
|
||||||
|
const key = args[4] || "";
|
||||||
|
|
||||||
|
if (principal && key) {
|
||||||
|
entries.push({ principal, realm, kvno, etypeInput, key });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entries.length === 0) {
|
||||||
|
throw new OperationError("No principal/key entries provided or found in input/arguments.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalEntries = [];
|
||||||
|
for (const entry of entries) {
|
||||||
|
const principal = entry.principal.trim();
|
||||||
|
const realm = entry.realm.trim() || "LOCAL";
|
||||||
|
const kvno = parseInt(entry.kvno, 10) || 1;
|
||||||
|
|
||||||
|
let etype = 23;
|
||||||
|
const etypeStr = String(entry.etypeInput).toLowerCase().trim();
|
||||||
|
if (etypeStr.includes("17") || etypeStr.includes("aes128")) {
|
||||||
|
etype = 17;
|
||||||
|
} else if (etypeStr.includes("18") || etypeStr.includes("aes256")) {
|
||||||
|
etype = 18;
|
||||||
|
} else if (etypeStr.includes("23") || etypeStr.includes("rc4") || etypeStr.includes("arcfour")) {
|
||||||
|
etype = 23;
|
||||||
|
} else {
|
||||||
|
const parsed = parseInt(etypeStr, 10);
|
||||||
|
if (!isNaN(parsed)) {
|
||||||
|
etype = parsed;
|
||||||
|
} else {
|
||||||
|
throw new OperationError(`Unsupported or unrecognized encryption type: ${entry.etypeInput}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cleanKey = entry.key.trim().replace(/^0x/i, "").replace(/[\s:]/g, "");
|
||||||
|
if (!/^[a-fA-F0-9]+$/.test(cleanKey)) {
|
||||||
|
throw new OperationError(`Key for principal ${principal} must be a hex-encoded string.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyLengthInBytes = cleanKey.length / 2;
|
||||||
|
if (etype === 23 && keyLengthInBytes !== 16) {
|
||||||
|
throw new OperationError(`RC4 key (etype 23) for principal ${principal} must be 16 bytes (32 hex characters). Got ${keyLengthInBytes} bytes.`);
|
||||||
|
} else if (etype === 17 && keyLengthInBytes !== 16) {
|
||||||
|
throw new OperationError(`AES128 key (etype 17) for principal ${principal} must be 16 bytes (32 hex characters). Got ${keyLengthInBytes} bytes.`);
|
||||||
|
} else if (etype === 18 && keyLengthInBytes !== 32) {
|
||||||
|
throw new OperationError(`AES256 key (etype 18) for principal ${principal} must be 32 bytes (64 hex characters). Got ${keyLengthInBytes} bytes.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyBytes = Utils.convertToByteArray(cleanKey, "hex");
|
||||||
|
finalEntries.push({ principal, realm, kvno, etype, keyBytes, cleanKey });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the binary keytab data
|
||||||
|
let totalLength = 2; // For format version bytes [0x05, 0x02]
|
||||||
|
const serializedEntries = [];
|
||||||
|
for (const entry of finalEntries) {
|
||||||
|
const bytes = serializeEntry(entry.principal, entry.realm, entry.kvno, entry.etype, new Uint8Array(entry.keyBytes));
|
||||||
|
serializedEntries.push(bytes);
|
||||||
|
totalLength += bytes.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
const keytabFile = new Uint8Array(totalLength);
|
||||||
|
keytabFile[0] = 0x05;
|
||||||
|
keytabFile[1] = 0x02;
|
||||||
|
let offset = 2;
|
||||||
|
for (const bytes of serializedEntries) {
|
||||||
|
keytabFile.set(bytes, offset);
|
||||||
|
offset += bytes.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
const outputFormat = args[5];
|
||||||
|
switch (outputFormat) {
|
||||||
|
case "Raw Keytab File":
|
||||||
|
return Array.from(keytabFile);
|
||||||
|
case "Hex": {
|
||||||
|
const hexStr = Array.from(keytabFile).map(b => b.toString(16).padStart(2, "0")).join("");
|
||||||
|
return Utils.strToByteArray(hexStr);
|
||||||
|
}
|
||||||
|
case "Base64": {
|
||||||
|
// Convert byteArray to string of chars, then base64 encode
|
||||||
|
const chars = Utils.byteArrayToChars(Array.from(keytabFile));
|
||||||
|
const b64 = btoa(chars);
|
||||||
|
return Utils.strToByteArray(b64);
|
||||||
|
}
|
||||||
|
case "Detailed Summary Text": {
|
||||||
|
let out = `Kerberos KRB5 Keytab Generation Summary:\n`;
|
||||||
|
out += `-----------------------------------------\n`;
|
||||||
|
out += `Successfully generated a keytab file with ${finalEntries.length} entries:\n\n`;
|
||||||
|
|
||||||
|
finalEntries.forEach((entry, idx) => {
|
||||||
|
let etypeName = "Unknown";
|
||||||
|
if (entry.etype === 23) etypeName = "RC4-HMAC (23)";
|
||||||
|
else if (entry.etype === 17) etypeName = "AES128-CTS-HMAC-SHA1-96 (17)";
|
||||||
|
else if (entry.etype === 18) etypeName = "AES256-CTS-HMAC-SHA1-96 (18)";
|
||||||
|
|
||||||
|
out += `Entry ${idx + 1}:\n`;
|
||||||
|
out += ` Principal: ${entry.principal}\n`;
|
||||||
|
out += ` Realm: ${entry.realm}\n`;
|
||||||
|
out += ` KVNO: ${entry.kvno}\n`;
|
||||||
|
out += ` Etype: ${etypeName}\n`;
|
||||||
|
out += ` Key (Hex): ${entry.cleanKey}\n\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
out += `Wireshark Configuration Instructions:\n`;
|
||||||
|
out += `-------------------------------------\n`;
|
||||||
|
out += `1. Save the generated keytab output as a file (e.g. krb5.keytab).\n`;
|
||||||
|
out += `2. Open Wireshark and go to: Edit -> Preferences -> Protocols -> KRB5\n`;
|
||||||
|
out += `3. Enable "Decrypt Kerberos traffic" (if available).\n`;
|
||||||
|
out += `4. Click "Browse..." next to "Kerberos keytab file" and select the generated file.\n`;
|
||||||
|
out += `5. Wireshark will now automatically decrypt Kerberos, DCE/RPC, LDAP, and SMB traffic where these keys are valid.\n`;
|
||||||
|
|
||||||
|
return Utils.strToByteArray(out);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new OperationError(`Unknown output format: ${outputFormat}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GenerateKerberosKeytab;
|
||||||
84
tests/operations/tests/GenerateKerberosKeytab.mjs
Normal file
84
tests/operations/tests/GenerateKerberosKeytab.mjs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Generate Kerberos Keytab operation tests
|
||||||
|
*
|
||||||
|
* @author mansiverma897993
|
||||||
|
* @copyright Crown Copyright 2026
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import TestRegister from "../../lib/TestRegister.mjs";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "Generate Kerberos Keytab: Single key via UI args (RC4)",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "05020000003b00010009574f524b47524f5550000b657368656c6c7374726f70000000010000000001001700103f29138a04aadc19214e9c04028bf38100000001",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Generate Kerberos Keytab",
|
||||||
|
args: [
|
||||||
|
"eshellstrop",
|
||||||
|
"WORKGROUP",
|
||||||
|
1,
|
||||||
|
"RC4-HMAC (23)",
|
||||||
|
"3f29138a04aadc19214e9c04028bf381",
|
||||||
|
"Hex"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Generate Kerberos Keytab: Multiple keys via CSV input",
|
||||||
|
input: "eshellstrop,WORKGROUP,1,23,3f29138a04aadc19214e9c04028bf381\ncifs/server.example.local,EXAMPLE.LOCAL,2,18,00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff",
|
||||||
|
expectedOutput: "05020000003b00010009574f524b47524f5550000b657368656c6c7374726f70000000010000000001001700103f29138a04aadc19214e9c04028bf381000000010000005e0002000d4558414d504c452e4c4f43414c00046369667300147365727665722e6578616d706c652e6c6f63616c0000000100000000020012002000112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00000002",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Generate Kerberos Keytab",
|
||||||
|
args: [
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
1,
|
||||||
|
"RC4-HMAC (23)",
|
||||||
|
"",
|
||||||
|
"Hex"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Generate Kerberos Keytab: JSON input format",
|
||||||
|
input: '[\n {"principal": "eshellstrop", "realm": "WORKGROUP", "kvno": 1, "etype": 23, "key": "3f29138a04aadc19214e9c04028bf381"}\n]',
|
||||||
|
expectedOutput: "05020000003b00010009574f524b47524f5550000b657368656c6c7374726f70000000010000000001001700103f29138a04aadc19214e9c04028bf38100000001",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Generate Kerberos Keytab",
|
||||||
|
args: [
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
1,
|
||||||
|
"RC4-HMAC (23)",
|
||||||
|
"",
|
||||||
|
"Hex"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Generate Kerberos Keytab: Detailed Summary Text output",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "Kerberos KRB5 Keytab Generation Summary:\n-----------------------------------------\nSuccessfully generated a keytab file with 1 entries:\n\nEntry 1:\n Principal: eshellstrop\n Realm: WORKGROUP\n KVNO: 1\n Etype: RC4-HMAC (23)\n Key (Hex): 3f29138a04aadc19214e9c04028bf381\n\nWireshark Configuration Instructions:\n-------------------------------------\n1. Save the generated keytab output as a file (e.g. krb5.keytab).\n2. Open Wireshark and go to: Edit -> Preferences -> Protocols -> KRB5\n3. Enable \"Decrypt Kerberos traffic\" (if available).\n4. Click \"Browse...\" next to \"Kerberos keytab file\" and select the generated file.\n5. Wireshark will now automatically decrypt Kerberos, DCE/RPC, LDAP, and SMB traffic where these keys are valid.\n",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Generate Kerberos Keytab",
|
||||||
|
args: [
|
||||||
|
"eshellstrop",
|
||||||
|
"WORKGROUP",
|
||||||
|
1,
|
||||||
|
"RC4-HMAC (23)",
|
||||||
|
"3f29138a04aadc19214e9c04028bf381",
|
||||||
|
"Detailed Summary Text"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
Loading…
x
Reference in New Issue
Block a user