mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-22 15:56:16 -04:00
Merge branch 'feature-extract-files' of github.com:gchq/CyberChef into feature-extract-files
This commit is contained in:
commit
f355fe3447
13 changed files with 980 additions and 734 deletions
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Magic from "../lib/Magic";
|
||||
import {detectFileType} from "../lib/FileType";
|
||||
|
||||
/**
|
||||
* Detect File Type operation
|
||||
|
@ -34,17 +34,21 @@ class DetectFileType extends Operation {
|
|||
*/
|
||||
run(input, args) {
|
||||
const data = new Uint8Array(input),
|
||||
type = Magic.magicFileType(data);
|
||||
types = detectFileType(data);
|
||||
|
||||
if (!type) {
|
||||
if (!types.length) {
|
||||
return "Unknown file type. Have you tried checking the entropy of this data to determine whether it might be encrypted or compressed?";
|
||||
} else {
|
||||
let output = "File extension: " + type.ext + "\n" +
|
||||
"MIME type: " + type.mime;
|
||||
let output = "";
|
||||
|
||||
if (type.desc && type.desc.length) {
|
||||
output += "\nDescription: " + type.desc;
|
||||
}
|
||||
types.forEach(type => {
|
||||
output += "File extension: " + type.extension + "\n" +
|
||||
"MIME type: " + type.mime + "\n";
|
||||
|
||||
if (type.description && type.description.length) {
|
||||
output += "\nDescription: " + type.description + "\n";
|
||||
}
|
||||
});
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
|
||||
import Operation from "../Operation";
|
||||
// import OperationError from "../errors/OperationError";
|
||||
import Magic from "../lib/Magic";
|
||||
import Utils from "../Utils";
|
||||
import {extractFile} from "../lib/FileExtraction";
|
||||
import {detectFileType, extractFile} from "../lib/FileType";
|
||||
|
||||
/**
|
||||
* Extract Files operation
|
||||
|
@ -40,13 +39,13 @@ class ExtractFiles extends Operation {
|
|||
const bytes = new Uint8Array(input);
|
||||
|
||||
// Scan for embedded files
|
||||
const fileDetails = scanForEmbeddedFiles(bytes);
|
||||
const detectedFiles = scanForEmbeddedFiles(bytes);
|
||||
|
||||
// Extract each file that we support
|
||||
const files = [];
|
||||
fileDetails.forEach(fileDetail => {
|
||||
detectedFiles.forEach(detectedFile => {
|
||||
try {
|
||||
files.push(extractFile(bytes, fileDetail));
|
||||
files.push(extractFile(bytes, detectedFile.fileDetails, detectedFile.offset));
|
||||
} catch (err) {}
|
||||
});
|
||||
|
||||
|
@ -70,22 +69,21 @@ class ExtractFiles extends Operation {
|
|||
* @param data
|
||||
*/
|
||||
function scanForEmbeddedFiles(data) {
|
||||
let type;
|
||||
const types = [];
|
||||
const detectedFiles = [];
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
type = Magic.magicFileType(data.slice(i));
|
||||
if (type) {
|
||||
types.push({
|
||||
offset: i,
|
||||
ext: type.ext,
|
||||
mime: type.mime,
|
||||
desc: type.desc
|
||||
const fileDetails = detectFileType(data.slice(i));
|
||||
if (fileDetails.length) {
|
||||
fileDetails.forEach(match => {
|
||||
detectedFiles.push({
|
||||
offset: i,
|
||||
fileDetails: match,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
return detectedFiles;
|
||||
}
|
||||
|
||||
export default ExtractFiles;
|
||||
|
|
|
@ -9,7 +9,7 @@ import { fromHex } from "../lib/Hex";
|
|||
import Operation from "../Operation";
|
||||
import OperationError from "../errors/OperationError";
|
||||
import Utils from "../Utils";
|
||||
import Magic from "../lib/Magic";
|
||||
import { detectFileType } from "../lib/FileType";
|
||||
|
||||
/**
|
||||
* PlayMedia operation
|
||||
|
@ -66,8 +66,8 @@ class PlayMedia extends Operation {
|
|||
|
||||
|
||||
// Determine file type
|
||||
const type = Magic.magicFileType(input);
|
||||
if (!(type && /^audio|video/.test(type.mime))) {
|
||||
const types = detectFileType(input);
|
||||
if (!(types && types.length && /^audio|video/.test(types[0].mime))) {
|
||||
throw new OperationError("Invalid or unrecognised file type");
|
||||
}
|
||||
|
||||
|
@ -84,15 +84,15 @@ class PlayMedia extends Operation {
|
|||
async present(data) {
|
||||
if (!data.length) return "";
|
||||
|
||||
const type = Magic.magicFileType(data);
|
||||
const matches = /^audio|video/.exec(type.mime);
|
||||
const types = detectFileType(data);
|
||||
const matches = /^audio|video/.exec(types[0].mime);
|
||||
if (!matches) {
|
||||
throw new OperationError("Invalid file type");
|
||||
}
|
||||
const dataURI = `data:${type.mime};base64,${toBase64(data)}`;
|
||||
const dataURI = `data:${types[0].mime};base64,${toBase64(data)}`;
|
||||
const element = matches[0];
|
||||
|
||||
let html = `<${element} src='${dataURI}' type='${type.mime}' controls>`;
|
||||
let html = `<${element} src='${dataURI}' type='${types[0].mime}' controls>`;
|
||||
html += "<p>Unsupported media type.</p>";
|
||||
html += `</${element}>`;
|
||||
return html;
|
||||
|
|
|
@ -9,7 +9,7 @@ import { fromHex } from "../lib/Hex";
|
|||
import Operation from "../Operation";
|
||||
import OperationError from "../errors/OperationError";
|
||||
import Utils from "../Utils";
|
||||
import Magic from "../lib/Magic";
|
||||
import {detectFileType} from "../lib/FileType";
|
||||
|
||||
/**
|
||||
* Render Image operation
|
||||
|
@ -72,8 +72,8 @@ class RenderImage extends Operation {
|
|||
}
|
||||
|
||||
// Determine file type
|
||||
const type = Magic.magicFileType(input);
|
||||
if (!(type && type.mime.indexOf("image") === 0)) {
|
||||
const types = detectFileType(input);
|
||||
if (!(types.length && types[0].mime.indexOf("image") === 0)) {
|
||||
throw new OperationError("Invalid file type");
|
||||
}
|
||||
|
||||
|
@ -92,9 +92,9 @@ class RenderImage extends Operation {
|
|||
let dataURI = "data:";
|
||||
|
||||
// Determine file type
|
||||
const type = Magic.magicFileType(data);
|
||||
if (type && type.mime.indexOf("image") === 0) {
|
||||
dataURI += type.mime + ";";
|
||||
const types = detectFileType(data);
|
||||
if (types.length && types[0].mime.indexOf("image") === 0) {
|
||||
dataURI += types[0].mime + ";";
|
||||
} else {
|
||||
throw new OperationError("Invalid file type");
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import Magic from "../lib/Magic";
|
||||
import {detectFileType} from "../lib/FileType";
|
||||
|
||||
/**
|
||||
* Scan for Embedded Files operation
|
||||
|
@ -41,7 +41,7 @@ class ScanForEmbeddedFiles extends Operation {
|
|||
*/
|
||||
run(input, args) {
|
||||
let output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any suffiently long file is likely to contain these magic bytes coincidentally.\n",
|
||||
type,
|
||||
types,
|
||||
numFound = 0,
|
||||
numCommonFound = 0;
|
||||
const ignoreCommon = args[0],
|
||||
|
@ -49,20 +49,23 @@ class ScanForEmbeddedFiles extends Operation {
|
|||
data = new Uint8Array(input);
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
type = Magic.magicFileType(data.slice(i));
|
||||
if (type) {
|
||||
if (ignoreCommon && commonExts.indexOf(type.ext) > -1) {
|
||||
numCommonFound++;
|
||||
continue;
|
||||
}
|
||||
numFound++;
|
||||
output += "\nOffset " + i + " (0x" + Utils.hex(i) + "):\n" +
|
||||
" File extension: " + type.ext + "\n" +
|
||||
" MIME type: " + type.mime + "\n";
|
||||
types = detectFileType(data.slice(i));
|
||||
if (types.length) {
|
||||
types.forEach(type => {
|
||||
if (ignoreCommon && commonExts.indexOf(type.extension) > -1) {
|
||||
numCommonFound++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (type.desc && type.desc.length) {
|
||||
output += " Description: " + type.desc + "\n";
|
||||
}
|
||||
numFound++;
|
||||
output += "\nOffset " + i + " (0x" + Utils.hex(i) + "):\n" +
|
||||
" File extension: " + type.extension + "\n" +
|
||||
" MIME type: " + type.mime + "\n";
|
||||
|
||||
if (type.description && type.description.length) {
|
||||
output += " Description: " + type.description + "\n";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue