mirror of
https://github.com/gchq/CyberChef.git
synced 2024-11-16 08:58:30 +01:00
Merge branch 'bwhitn-unzipmod'
This commit is contained in:
commit
2f0121f0e4
6 changed files with 75 additions and 94 deletions
|
@ -73,7 +73,7 @@ Ingredient.prepare = function(data, type) {
|
||||||
case "byteArray":
|
case "byteArray":
|
||||||
if (typeof data == "string") {
|
if (typeof data == "string") {
|
||||||
data = data.replace(/\s+/g, "");
|
data = data.replace(/\s+/g, "");
|
||||||
return Utils.hexToByteArray(data);
|
return Utils.fromHex(data);
|
||||||
} else {
|
} else {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -340,50 +340,6 @@ const Utils = {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translates a hex string into an array of bytes.
|
|
||||||
*
|
|
||||||
* @param {string} hexStr
|
|
||||||
* @returns {byteArray}
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* // returns [0xfe, 0x09, 0xa7]
|
|
||||||
* Utils.hexToByteArray("fe09a7");
|
|
||||||
*/
|
|
||||||
hexToByteArray: function(hexStr) {
|
|
||||||
// TODO: Handle errors i.e. input string is not hex
|
|
||||||
if (!hexStr) return [];
|
|
||||||
hexStr = hexStr.replace(/\s+/g, "");
|
|
||||||
const byteArray = [];
|
|
||||||
for (let i = 0; i < hexStr.length; i += 2) {
|
|
||||||
byteArray.push(parseInt(hexStr.substr(i, 2), 16));
|
|
||||||
}
|
|
||||||
return byteArray;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translates an array of bytes to a hex string.
|
|
||||||
*
|
|
||||||
* @param {byteArray} byteArray
|
|
||||||
* @param {string} [delim=" "]
|
|
||||||
* @returns {string}
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* // returns "fe09a7"
|
|
||||||
* Utils.byteArrayToHex([0xfe, 0x09, 0xa7], "");
|
|
||||||
*/
|
|
||||||
byteArrayToHex: function(byteArray, delim) {
|
|
||||||
if (!byteArray) return "";
|
|
||||||
delim = typeof delim === "undefined" ? " " : delim;
|
|
||||||
let hexStr = "";
|
|
||||||
for (let i = 0; i < byteArray.length; i++) {
|
|
||||||
hexStr += Utils.hex(byteArray[i]) + delim;
|
|
||||||
}
|
|
||||||
return hexStr.slice(0, hexStr.length - delim.length);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a string to a byte array.
|
* Converts a string to a byte array.
|
||||||
* Treats the string as UTF-8 if any values are over 255.
|
* Treats the string as UTF-8 if any values are over 255.
|
||||||
|
@ -828,7 +784,7 @@ const Utils = {
|
||||||
if (removeScriptAndStyle) {
|
if (removeScriptAndStyle) {
|
||||||
htmlStr = htmlStr.replace(/<(script|style)[^>]*>.*<\/(script|style)>/gmi, "");
|
htmlStr = htmlStr.replace(/<(script|style)[^>]*>.*<\/(script|style)>/gmi, "");
|
||||||
}
|
}
|
||||||
return htmlStr.replace(/<[^>\n]+>/g, "");
|
return htmlStr.replace(/<[^>]+>/g, "");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -946,16 +902,19 @@ const Utils = {
|
||||||
* @returns {html}
|
* @returns {html}
|
||||||
*/
|
*/
|
||||||
displayFilesAsHTML: function(files) {
|
displayFilesAsHTML: function(files) {
|
||||||
|
/* <NL> and <SP> used to denote newlines and spaces in HTML markup.
|
||||||
|
* If a non-html operation is used, all markup will be removed but these
|
||||||
|
* whitespace chars will remain for formatting purposes.
|
||||||
|
*/
|
||||||
|
|
||||||
const formatDirectory = function(file) {
|
const formatDirectory = function(file) {
|
||||||
const html = "<div class='panel panel-default'>" +
|
const html = `<div class='panel panel-default' style='white-space: normal;'>
|
||||||
"<div class='panel-heading' role='tab'>" +
|
<div class='panel-heading' role='tab'>
|
||||||
"<h4 class='panel-title'>" +
|
<h4 class='panel-title'>
|
||||||
Utils.escapeHtml(file.fileName) +
|
<NL>${Utils.escapeHtml(file.fileName)}
|
||||||
// The following line is for formatting when HTML is stripped
|
</h4>
|
||||||
"<span style='display: none'>\n0 bytes\n</span>" +
|
</div>
|
||||||
"</h4>" +
|
</div>`;
|
||||||
"</div>" +
|
|
||||||
"</div>";
|
|
||||||
return html;
|
return html;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -966,45 +925,52 @@ const Utils = {
|
||||||
);
|
);
|
||||||
const blobUrl = URL.createObjectURL(blob);
|
const blobUrl = URL.createObjectURL(blob);
|
||||||
|
|
||||||
const downloadAnchorElem = "<a href='" + blobUrl + "' " +
|
const viewFileElem = `<a href='#collapse${i}'
|
||||||
"title='Download " + Utils.escapeHtml(file.fileName) + "' " +
|
class='collapsed'
|
||||||
"download='" + Utils.escapeHtml(file.fileName) + "'>\u21B4</a>";
|
data-toggle='collapse'
|
||||||
|
aria-expanded='true'
|
||||||
|
aria-controls='collapse${i}'
|
||||||
|
title="Show/hide contents of '${Utils.escapeHtml(file.fileName)}'">👁️</a>`;
|
||||||
|
|
||||||
const expandFileContentsElem = "<a href='#collapse" + i + "' " +
|
const downloadFileElem = `<a href='${blobUrl}'
|
||||||
"class='collapsed' " +
|
title='Download ${Utils.escapeHtml(file.fileName)}'
|
||||||
"data-toggle='collapse' " +
|
download='${Utils.escapeHtml(file.fileName)}'>💾</a>`;
|
||||||
"aria-expanded='true' " +
|
|
||||||
"aria-controls='collapse" + i + "' " +
|
|
||||||
"title=\"Show/hide contents of '" + Utils.escapeHtml(file.fileName) + "'\">🔍</a>";
|
|
||||||
|
|
||||||
const html = "<div class='panel panel-default'>" +
|
const hexFileData = Utils.toHexFast(new Uint8Array(file.bytes));
|
||||||
"<div class='panel-heading' role='tab' id='heading" + i + "'>" +
|
|
||||||
"<h4 class='panel-title'>" +
|
const switchToInputElem = `<a href='#switchFileToInput${i}'
|
||||||
"<div>" +
|
class='file-switch'
|
||||||
Utils.escapeHtml(file.fileName) +
|
title='Move file to input as hex'
|
||||||
" " + expandFileContentsElem +
|
fileValue='${hexFileData}'>⇧</a>`;
|
||||||
" " + downloadAnchorElem +
|
|
||||||
"<span class='pull-right'>" +
|
const html = `<div class='panel panel-default' style='white-space: normal;'>
|
||||||
// These are for formatting when stripping HTML
|
<div class='panel-heading' role='tab' id='heading${i}'>
|
||||||
"<span style='display: none'>\n</span>" +
|
<h4 class='panel-title'>
|
||||||
file.size.toLocaleString() + " bytes" +
|
<div>
|
||||||
"<span style='display: none'>\n</span>" +
|
${Utils.escapeHtml(file.fileName)}<NL>
|
||||||
"</span>" +
|
${viewFileElem}<SP>
|
||||||
"</div>" +
|
${downloadFileElem}<SP>
|
||||||
"</h4>" +
|
${switchToInputElem}<SP>
|
||||||
"</div>" +
|
<span class='pull-right'>
|
||||||
"<div id='collapse" + i + "' class='panel-collapse collapse' " +
|
<NL>${file.size.toLocaleString()} bytes
|
||||||
"role='tabpanel' aria-labelledby='heading" + i + "'>" +
|
</span>
|
||||||
"<div class='panel-body'>" +
|
</div>
|
||||||
"<pre><code>" + Utils.escapeHtml(file.contents) + "</pre></code></div>" +
|
</h4>
|
||||||
"</div>" +
|
</div>
|
||||||
"</div>";
|
<div id='collapse${i}' class='panel-collapse collapse'
|
||||||
|
role='tabpanel' aria-labelledby='heading${i}'>
|
||||||
|
<div class='panel-body'>
|
||||||
|
<NL><NL><pre><code>${Utils.escapeHtml(file.contents)}</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
return html;
|
return html;
|
||||||
};
|
};
|
||||||
|
|
||||||
let html = "<div style='padding: 5px;'>" +
|
let html = `<div style='padding: 5px; white-space: normal;'>
|
||||||
files.length +
|
${files.length} file(s) found<NL>
|
||||||
" file(s) found</div>\n";
|
</div>`;
|
||||||
|
|
||||||
files.forEach(function(file, i) {
|
files.forEach(function(file, i) {
|
||||||
if (typeof file.contents !== "undefined") {
|
if (typeof file.contents !== "undefined") {
|
||||||
html += formatFile(file, i);
|
html += formatFile(file, i);
|
||||||
|
@ -1012,7 +978,10 @@ const Utils = {
|
||||||
html += formatDirectory(file);
|
html += formatDirectory(file);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return html;
|
|
||||||
|
return html.replace(/(?:(<pre>(?:\n|.)*<\/pre>)|\s{2,})/g, "$1") // Remove whitespace from markup
|
||||||
|
.replace(/<NL>/g, "\n") // Replace <NP> with newlines
|
||||||
|
.replace(/<SP>/g, " "); // Replace <SP> with spaces
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -142,12 +142,12 @@ const BitwiseOp = {
|
||||||
|
|
||||||
|
|
||||||
for (let key = 1, l = Math.pow(256, keyLength); key < l; key++) {
|
for (let key = 1, l = Math.pow(256, keyLength); key < l; key++) {
|
||||||
result = BitwiseOp._bitOp(input, Utils.hexToByteArray(key.toString(16)), BitwiseOp._xor, nullPreserving, differential);
|
result = BitwiseOp._bitOp(input, Utils.fromHex(key.toString(16)), BitwiseOp._xor, nullPreserving, differential);
|
||||||
resultUtf8 = Utils.byteArrayToUtf8(result);
|
resultUtf8 = Utils.byteArrayToUtf8(result);
|
||||||
if (crib !== "" && resultUtf8.search(regex) === -1) continue;
|
if (crib !== "" && resultUtf8.search(regex) === -1) continue;
|
||||||
if (printKey) output += "Key = " + Utils.hex(key, (2*keyLength)) + ": ";
|
if (printKey) output += "Key = " + Utils.hex(key, (2*keyLength)) + ": ";
|
||||||
if (outputHex)
|
if (outputHex)
|
||||||
output += Utils.byteArrayToHex(result) + "\n";
|
output += Utils.toHex(result) + "\n";
|
||||||
else
|
else
|
||||||
output += Utils.printable(resultUtf8, false) + "\n";
|
output += Utils.printable(resultUtf8, false) + "\n";
|
||||||
if (printKey) output += "\n";
|
if (printKey) output += "\n";
|
||||||
|
|
|
@ -283,7 +283,7 @@ const IP = {
|
||||||
baIp.push(decimal & 255);
|
baIp.push(decimal & 255);
|
||||||
break;
|
break;
|
||||||
case "Hex":
|
case "Hex":
|
||||||
baIp = Utils.hexToByteArray(lines[i]);
|
baIp = Utils.fromHex(lines[i]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw "Unsupported input IP format";
|
throw "Unsupported input IP format";
|
||||||
|
@ -516,7 +516,7 @@ const IP = {
|
||||||
"<tr><td>Destination IP address</td><td>" + IP._ipv4ToStr(dstIP) + "</td></tr>";
|
"<tr><td>Destination IP address</td><td>" + IP._ipv4ToStr(dstIP) + "</td></tr>";
|
||||||
|
|
||||||
if (ihl > 5) {
|
if (ihl > 5) {
|
||||||
output += "<tr><td>Options</td><td>" + Utils.byteArrayToHex(options) + "</td></tr>";
|
output += "<tr><td>Options</td><td>" + Utils.toHex(options) + "</td></tr>";
|
||||||
}
|
}
|
||||||
|
|
||||||
return output + "</table>";
|
return output + "</table>";
|
||||||
|
|
|
@ -145,6 +145,7 @@ Manager.prototype.initialiseEventListeners = function() {
|
||||||
document.getElementById("output-html").addEventListener("mousemove", this.highlighter.outputHtmlMousemove.bind(this.highlighter));
|
document.getElementById("output-html").addEventListener("mousemove", this.highlighter.outputHtmlMousemove.bind(this.highlighter));
|
||||||
this.addMultiEventListener("#output-text", "mousedown dblclick select", this.highlighter.outputMousedown, this.highlighter);
|
this.addMultiEventListener("#output-text", "mousedown dblclick select", this.highlighter.outputMousedown, this.highlighter);
|
||||||
this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter);
|
this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter);
|
||||||
|
this.addDynamicListener(".file-switch", "click", this.output.fileSwitch, this.output);
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options));
|
document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options));
|
||||||
|
|
|
@ -167,6 +167,17 @@ OutputWaiter.prototype.undoSwitchClick = function() {
|
||||||
document.getElementById("undo-switch").disabled = true;
|
document.getElementById("undo-switch").disabled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for file switch click events.
|
||||||
|
* Moves a files data for items created via Utils.displayFilesAsHTML to the input.
|
||||||
|
*/
|
||||||
|
OutputWaiter.prototype.fileSwitch = function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.switchOrigData = this.manager.input.get();
|
||||||
|
this.app.setInput(e.target.getAttribute("fileValue"));
|
||||||
|
document.getElementById("undo-switch").disabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for maximise output click events.
|
* Handler for maximise output click events.
|
||||||
|
|
Loading…
Reference in a new issue