diff --git a/web/src/components/Results.vue b/web/src/components/Results.vue
index 7140bf7e..35b012e1 100644
--- a/web/src/components/Results.vue
+++ b/web/src/components/Results.vue
@@ -259,7 +259,11 @@
{{ stream.Stream.FirstPacket | formatDate }}
-
+
mdi-download
|
diff --git a/web/src/components/Stream.vue b/web/src/components/Stream.vue
index 90141fe2..9830840b 100644
--- a/web/src/components/Stream.vue
+++ b/web/src/components/Stream.vue
@@ -45,6 +45,20 @@
Search Selection
+
+
+ mdi-chef-hat
+
+ Open in CyberChef
+
@@ -315,6 +329,8 @@ import {
import { mapActions, mapGetters, mapState } from "vuex";
import ToolBar from "./ToolBar.vue";
+const CYBERCHEF_URL = "https://gchq.github.io/CyberChef/";
+
export default {
name: "Stream",
components: { StreamData, ToolBar },
@@ -325,6 +341,7 @@ export default {
}
return {
presentation: p,
+ selectionData: "",
selectionQuery: "",
};
},
@@ -450,6 +467,16 @@ export default {
document.getSelection().empty();
}
},
+ openInCyberChef() {
+ let data = this.selectionData;
+ if (data === "") {
+ for (const chunk of this.stream.stream.Data) {
+ data += atob(chunk.Content);
+ }
+ }
+ const encoded_data = btoa(data);
+ window.open(`${CYBERCHEF_URL}#input=${encodeURIComponent(encoded_data)}`);
+ },
createMark() {
EventBus.$emit("showCreateTagDialog", {
tagType: "mark",
diff --git a/web/src/components/streamSelector.js b/web/src/components/streamSelector.js
index 3e1d1029..c1c4344c 100644
--- a/web/src/components/streamSelector.js
+++ b/web/src/components/streamSelector.js
@@ -48,20 +48,20 @@ function escape(text) {
.join("");
}
-function chunkToQueryPart(chunk, start, length = undefined) {
- return `${"cs"[chunk.Direction]}data:"${escape(
- atob(chunk.Content).substring(start, length)
- )}"`;
+function chunkToQueryPart(chunk, data) {
+ return `${"cs"[chunk.Direction]}data:"${escape(data)}"`;
}
function onSelectionChange() {
const selection = document.getSelection();
if (selection.type !== "Range" || selection.isCollapsed) {
+ this.selectionData = "";
this.selectionQuery = "";
return;
}
const streamDataNode = this.$refs.streamData?.$el ?? this.$refs.streamData;
if (selection.rangeCount !== 1 || streamDataNode == null) {
+ this.selectionData = "";
this.selectionQuery = "";
return;
}
@@ -83,6 +83,7 @@ function onSelectionChange() {
!streamDataNode.contains(startContainer) ||
!streamDataNode.contains(endContainer)
) {
+ this.selectionData = "";
this.selectionQuery = "";
return;
}
@@ -104,28 +105,32 @@ function onSelectionChange() {
(i) => i === null
)
) {
+ this.selectionData = "";
this.selectionQuery = "";
return;
}
if (startChunkIdx >= chunks.length) {
+ this.selectionData = "";
this.selectionQuery = "";
return;
}
+ let queryData = "";
let queryParts = [];
for (
let currentChunkIdx = startChunkIdx;
currentChunkIdx <= endChunkIdx;
currentChunkIdx++
) {
- queryParts.push(
- chunkToQueryPart(
- chunks[currentChunkIdx],
- currentChunkIdx === startChunkIdx ? startChunkOffset : 0,
- currentChunkIdx === endChunkIdx ? endChunkOffset + 1 : undefined
- )
- );
+ const chunk = chunks[currentChunkIdx];
+ const start = currentChunkIdx === startChunkIdx ? startChunkOffset : 0;
+ const end =
+ currentChunkIdx === endChunkIdx ? endChunkOffset + 1 : undefined;
+ const data = atob(chunk.Content).substring(start, end);
+ queryData += data;
+ queryParts.push(chunkToQueryPart(chunk, data));
}
+ this.selectionData = queryData;
this.selectionQuery = queryParts.join(" then ");
}