mirror of
https://github.com/gchq/CyberChef.git
synced 2025-05-09 07:45:00 -04:00
Have some initial functionallity
This commit is contained in:
parent
189cf337d6
commit
9ef9dff832
1 changed files with 76 additions and 37 deletions
|
@ -21,12 +21,10 @@ import Utils from "../Utils";
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
const IMF_FIELD_ITEM = {
|
const FILE_TYPE_SUFFIX = {
|
||||||
FILENAME: [/filename=".*?([^~#%&*\][\\:<>?/|]+)"/, "content-disposition"],
|
"text/plain": "txt",
|
||||||
CONTENT_TYPE: [/\s*([^;\s]+)/, "content-type"],
|
"text/html": "htm",
|
||||||
BOUNDARY: [/boundary="(.+?)"/, "content-type"],
|
"application/rtf": "rtf",
|
||||||
CHARSET: [/charset=([a-z0-9-]+)/, "content-type"],
|
|
||||||
TRANSER_ENCODING: [/\s*([A-Za-z0-9-]+)\s*/, "content-transfer-encoding"],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParseIMF extends Operation {
|
class ParseIMF extends Operation {
|
||||||
|
@ -64,22 +62,34 @@ class ParseIMF extends Operation {
|
||||||
* @returns {File[]}
|
* @returns {File[]}
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
|
// TODO: need to add Non-Mime emails
|
||||||
|
// TODO: need to add header info to output
|
||||||
|
// TODO: no uuencode function. see if we can fix this
|
||||||
|
// TODO: Need to parse multipart headers better as they are key value pairs separated by a ";\s+".
|
||||||
if (!input) {
|
if (!input) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
let headerBody = ParseIMF.splitHeaderFromBody(input);
|
let headerBody = ParseIMF.splitHeaderFromBody(input);
|
||||||
let header = headerBody[0];
|
let headerArray = ParseIMF.parseHeader(headerBody[0]);
|
||||||
let headerArray = ParseIMF.parseHeader(header);
|
|
||||||
if (args[0] && headerBody.length > 0) {
|
if (args[0] && headerBody.length > 0) {
|
||||||
headerBody[0] = ParseIMF.replaceDecodeWord(headerBody[0]);
|
headerBody[0] = ParseIMF.replaceDecodeWord(headerBody[0]);
|
||||||
}
|
}
|
||||||
let retfiles = ParseIMF.walkMime(headerBody[1], headerArray, input.indexOf("\r") >= 0);
|
let retfiles = ParseIMF.walkMime(headerBody[1], headerArray, input.indexOf("\r") >= 0);
|
||||||
let retval = [];
|
let retval = [];
|
||||||
let i = 0;
|
retfiles.forEach(function(fileObj){
|
||||||
retfiles.forEach(function(file){
|
let file = null;
|
||||||
file = new File([file.data], "test"+String(i), {type: "text/plain"});
|
if (fileObj.name !== null) {
|
||||||
|
file = new File([fileObj.data], fileObj.name, {type: fileObj.type});
|
||||||
|
} else {
|
||||||
|
let name = ParseIMF.replaceDecodeWord(headerArray["subject"][0]).concat(".");
|
||||||
|
if (fileObj.type in FILE_TYPE_SUFFIX) {
|
||||||
|
name = name.concat(FILE_TYPE_SUFFIX[fileObj.type]);
|
||||||
|
} else {
|
||||||
|
name = name.concat("bin");
|
||||||
|
}
|
||||||
|
file = new File([fileObj.data], name, {type: fileObj.type});
|
||||||
|
}
|
||||||
retval.push(file);
|
retval.push(file);
|
||||||
i++;
|
|
||||||
});
|
});
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -115,21 +125,37 @@ class ParseIMF extends Operation {
|
||||||
} else {
|
} else {
|
||||||
content_boundary = content_type_reg.exec(header["content-type"][0]);
|
content_boundary = content_type_reg.exec(header["content-type"][0]);
|
||||||
}
|
}
|
||||||
const boundary_str = "--".concat(content_boundary[idx]);
|
let mime_parts = ParseIMF.splitMultipart(input, content_boundary[idx], new_line_length);
|
||||||
let start = input.indexOf(boundary_str) + boundary_str.length + new_line_length;
|
mime_parts.forEach(function(mime_part){
|
||||||
let end = input.indexOf(boundary_str.concat("--")) - new_line_length;
|
let headerBody = ParseIMF.splitHeaderFromBody(mime_part);
|
||||||
let output = input.substring(start, end);
|
let headerArray = ParseIMF.parseHeader(headerBody[0]);
|
||||||
let headerBody = ParseIMF.splitHeaderFromBody(output);
|
let parts = ParseIMF.walkMime(headerBody[1], headerArray, rn);
|
||||||
let headerArray = ParseIMF.parseHeader(headerBody[0]);
|
parts.forEach(function(part){
|
||||||
let parts = ParseIMF.walkMime(headerBody[1], headerArray, rn);
|
output_sections.push(part);
|
||||||
parts.forEach(function(part){
|
});
|
||||||
output_sections.push(part);
|
|
||||||
});
|
});
|
||||||
} else if (header.hasOwnProperty("content-type") && header.hasOwnProperty("content-transfer-encoding")) {
|
} else if (header.hasOwnProperty("content-type") && header.hasOwnProperty("content-transfer-encoding")) {
|
||||||
const cont_type_data_reg = /^([^;]+);\s+charset\=(['"])(.+?)\2/g;
|
let contType = null;
|
||||||
let cont_type = cont_type_data_reg.exec(header["content-type"][0]);
|
let dataValue = null;
|
||||||
let val = ParseIMF.decodeMimeData(input, cont_type[3], header["content-transfer-encoding"][0]);
|
let fileName = null;
|
||||||
return [{type:cont_type[1], data: val}];
|
let charEnc = null;
|
||||||
|
// TODO: if there is no content disposition filename try content type name.
|
||||||
|
if (header.hasOwnProperty("content-disposition")) {
|
||||||
|
const cont_disp = /^([^;]+);.*?filename\=(['"]?)(.+?)\2$/g;
|
||||||
|
let dispo = cont_disp.exec(header["content-disposition"][0]);
|
||||||
|
// TODO: Remove path if it contains it.
|
||||||
|
fileName = dispo[3];
|
||||||
|
const cont_type_file = /^([^;]+);\s+name\=(["']?)(.+?)\2$/g;
|
||||||
|
let content = cont_type_file.exec(header["content-type"][0]);
|
||||||
|
let contType = content[1];
|
||||||
|
} else {
|
||||||
|
const cont_type_data_reg = /^([^;]+);\s+charset\=(['"]?)(.+?)\2$/g;
|
||||||
|
let content = cont_type_data_reg.exec(header["content-type"][0]);
|
||||||
|
contType = content[1];
|
||||||
|
charEnc = content[3]
|
||||||
|
}
|
||||||
|
dataValue = ParseIMF.decodeMimeData(input, charEnc, header["content-transfer-encoding"][0]);
|
||||||
|
return [{type: contType, data: dataValue, name: fileName}];
|
||||||
} else {
|
} else {
|
||||||
throw new OperationError("Invalid Mime section");
|
throw new OperationError("Invalid Mime section");
|
||||||
}
|
}
|
||||||
|
@ -178,7 +204,7 @@ class ParseIMF extends Operation {
|
||||||
* @returns {object}
|
* @returns {object}
|
||||||
*/
|
*/
|
||||||
static parseHeader(input) {
|
static parseHeader(input) {
|
||||||
const sectionRegex = /([A-Z-]+):\s+([\x20-\x7e\r\n\t]+?)(?=$|\r?\n\S)/gi;
|
const sectionRegex = /([A-Za-z-]+):\s+([\x20-\xff\r\n\t]+?)(?=$|\r?\n\S)/g;
|
||||||
let header = {}, section;
|
let header = {}, section;
|
||||||
while ((section = sectionRegex.exec(input))) {
|
while ((section = sectionRegex.exec(input))) {
|
||||||
let fieldName = section[1].toLowerCase();
|
let fieldName = section[1].toLowerCase();
|
||||||
|
@ -220,22 +246,35 @@ class ParseIMF extends Operation {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a header item given a header object, itemName, and index number.
|
|
||||||
*
|
*
|
||||||
* @param {object} header
|
*
|
||||||
* @param {object} FIELD_ITEM
|
*
|
||||||
* @param {integer} fieldNum
|
*
|
||||||
* @returns {string}
|
|
||||||
*/
|
*/
|
||||||
static getHeaderItem(header, fieldItem, fieldNum = 0){
|
static splitMultipart(input, boundary, new_line_length) {
|
||||||
if (fieldItem[1] in header && header[fieldItem[1]].length > fieldNum) {
|
let output = [];
|
||||||
let field = header[fieldItem[1]][fieldNum], item;
|
let newline = new_line_length === 2 ? "\r\n" : "\n";
|
||||||
if ((item = fieldItem[0].exec(field))) {
|
const boundary_str = "--".concat(boundary, newline);
|
||||||
return item[1];
|
const last = input.indexOf("--".concat(boundary, "--", newline)) - new_line_length;
|
||||||
|
let start = 0;
|
||||||
|
while(true) {
|
||||||
|
let start = input.indexOf(boundary_str, start);
|
||||||
|
if (start >= 0) {
|
||||||
|
start = start + boundary_str.length;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
let end = input.indexOf(boundary_str, start) - new_line_length;
|
||||||
|
if (end > start) {
|
||||||
|
output.push(input.substring(start, end));
|
||||||
|
} else {
|
||||||
|
output.push(input.substring(start, last));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
start = end;
|
||||||
}
|
}
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ParseIMF
|
export default ParseIMF
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue