mirror of
https://github.com/its-a-feature/Mythic
synced 2026-06-08 14:55:38 +00:00
UI v0.1.50
Dashboard tweaks for the UI and slight console view tweaks
This commit is contained in:
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.1.50] - 2024-01-09
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated the dashboard page to have more links to the search pages based on what you click
|
||||
- Updated the console view for a callback to move the speeddial button closer to the task itself
|
||||
|
||||
## [0.1.48] - 2024-01-08
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -8,6 +8,10 @@ COPY . .
|
||||
# Install dependencies (npm ci makes sure the exact versions in the lockfile gets installed)
|
||||
#RUN npm install --legacy-peer-deps
|
||||
RUN npm ci --legacy-peer-deps
|
||||
|
||||
ENV CHOKIDAR_USEPOLLING=true
|
||||
ENV WATCHPACK_POLLING=true
|
||||
ENV FAST_REFRESH=true
|
||||
ENV WDS_POLLING=true
|
||||
ENV WDS_SOCKET_PATH=ws
|
||||
# ==== RUN =====
|
||||
CMD CHOKIDAR_USEPOLLING=true WATCHPACK_POLLING=true FAST_REFRESH=true WDS_POLLING=true npm run react-start
|
||||
CMD CHOKIDAR_USEPOLLING=true WATCHPACK_POLLING=true FAST_REFRESH=true WDS_POLLING=true WDS_SOCKET_PATH=ws npm run react-start
|
||||
@@ -857,12 +857,12 @@ const SpeedDialDisplayConsole = ({toggleViewBrowserScript, toggleSelectAllOutput
|
||||
}
|
||||
<SpeedDial
|
||||
ariaLabel="Task Speeddial"
|
||||
icon={<SpeedDialIcon />}
|
||||
style={{position: "relative", float: "right", bottom: "0px", zIndex: 2, height: "0px", display: "inline-flex", flexDirection: "row-reverse"}}
|
||||
icon={<SpeedDialIcon />}
|
||||
style={{ bottom: "0px", zIndex: 2, height: "0px", flexDirection: "row", alignItems: "flex-start", position: "relative"}}
|
||||
onClick={()=>{setOpenSpeedDial(!openSpeedDial)}}
|
||||
FabProps={{color: "primary", size: "small" }}
|
||||
FabProps={{color: "primary", sx: {width: 25, height: 25, minHeight: 20} }}
|
||||
open={openSpeedDial}
|
||||
direction="left"
|
||||
direction="right"
|
||||
>
|
||||
<SpeedDialAction
|
||||
icon={<CodeIcon/>}
|
||||
|
||||
@@ -161,9 +161,42 @@ export function CallbacksCard() {
|
||||
//console.log(event, itemIdentifier, item);
|
||||
if(item.label.includes("not successful")){
|
||||
navigate("/new/search?searchField=Command&search=" + item.id + "&tab=tasks&taskStatus=error");
|
||||
} else {
|
||||
navigate("/new/search?searchField=Command&search=" + item.id + "&tab=tasks&taskStatus=");
|
||||
}
|
||||
|
||||
};
|
||||
const handlePortClick = (event, itemIdentifier, item) => {
|
||||
//console.log(event, itemIdentifier, item);
|
||||
navigate("/new/search?tab=socks");
|
||||
};
|
||||
const handleArtifactClick = (event, itemIdentifier, item) => {
|
||||
//console.log(event, itemIdentifier, item);
|
||||
navigate("/new/search?tab=artifacts&searchField=Type&search=" + item.id);
|
||||
};
|
||||
const handleTagClick = (event, itemIdentifier, item) => {
|
||||
//console.log(event, itemIdentifier, item);
|
||||
navigate("/new/search?tab=tags&searchField=TagType&search=" + item.id);
|
||||
};
|
||||
const handleUserContextClick = (user) => {
|
||||
let search = user.split(" ");
|
||||
search = search[search.length - 1];
|
||||
if(search.length > 0){
|
||||
if(search[0] === "*"){
|
||||
search = search.substring(1);
|
||||
}
|
||||
navigate("/new/search?searchField=User&search=" + search);
|
||||
}
|
||||
|
||||
}
|
||||
const handleHostContextClick = (host) => {
|
||||
let search = host.split(" ");
|
||||
search = search[search.length - 1];
|
||||
if(search.length > 0){
|
||||
navigate("/new/search?searchField=Host&search=" + search);
|
||||
}
|
||||
|
||||
}
|
||||
useQuery(GetCallbacks, {fetchPolicy: "network-only",
|
||||
onCompleted: (data) => {
|
||||
let callbackData = {};
|
||||
@@ -360,6 +393,25 @@ export function CallbacksCard() {
|
||||
taskedHostCounts[ "[" + curGroup + "] " + currentHost ] = 1;
|
||||
}
|
||||
}
|
||||
if(callbackData[cur.callback_id].mythictree_groups.length === 0){
|
||||
let currentTaskedUser = callbackData[cur.callback_id].user;
|
||||
if(callbackData[cur.callback_id].integrity_level > 2){
|
||||
currentTaskedUser = "*" + currentTaskedUser;
|
||||
}
|
||||
if( taskedUserCounts[ currentTaskedUser] ){
|
||||
taskedUserCounts[ currentTaskedUser] += 1;
|
||||
} else {
|
||||
taskedUserCounts[ currentTaskedUser] = 1;
|
||||
}
|
||||
|
||||
// get counts per tasked host
|
||||
let currentHost = callbackData[cur.callback_id].host;
|
||||
if(taskedHostCounts[ currentHost ]){
|
||||
taskedHostCounts[ currentHost ] += 1;
|
||||
} else {
|
||||
taskedHostCounts[ currentHost ] = 1;
|
||||
}
|
||||
}
|
||||
// get operator activity counts
|
||||
if(prev.includes(cur.operator.username)){
|
||||
return prev;
|
||||
@@ -566,8 +618,10 @@ export function CallbacksCard() {
|
||||
/>
|
||||
|
||||
<TableDataCard data={taskedUser} title={"Top User Contexts"} leftKey={"label"} rightKey={"value"}
|
||||
onRowClick={handleUserContextClick}
|
||||
leftColumnTitle={"User"} rightColumnTitle={"Tasks"} />
|
||||
<TableDataCard data={taskedHosts} title={"Top Active Hosts"} leftKey={"label"} rightKey={"value"}
|
||||
onRowClick={handleHostContextClick}
|
||||
leftColumnTitle={"Host"} rightColumnTitle={"Tasks"} />
|
||||
</div>
|
||||
<div style={{}}>
|
||||
@@ -590,16 +644,19 @@ export function CallbacksCard() {
|
||||
<PieChartCard data={taskArtifacts}
|
||||
innerElement={ <PieCenterLabel>Top Artifacts</PieCenterLabel> }
|
||||
hidden={true}
|
||||
onClick={handleArtifactClick}
|
||||
additionalStyles={{
|
||||
}}
|
||||
/>
|
||||
<PieChartCard data={tags}
|
||||
innerElement={ <PieCenterLabel>Top Tags</PieCenterLabel> }
|
||||
hidden={true}
|
||||
onClick={handleTagClick}
|
||||
additionalStyles={{
|
||||
}}
|
||||
/>
|
||||
<PieMultiChartCard data={callbackPorts}
|
||||
onClick={handlePortClick}
|
||||
title={"Port Usage"}
|
||||
hidden={true}
|
||||
/>
|
||||
@@ -627,7 +684,7 @@ const PieChartCard = ({data, width="100%", additionalStyles, innerElement, hidde
|
||||
right: 10,
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
}, colors=cheerfulFiestaPalette}) => {
|
||||
}, colors=cheerfulFiestaPalette, onClick}) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<Paper elevation={5} style={{
|
||||
@@ -678,6 +735,7 @@ const PieChartCard = ({data, width="100%", additionalStyles, innerElement, hidde
|
||||
},
|
||||
}}
|
||||
colors={colors}
|
||||
onClick={onClick}
|
||||
>
|
||||
{innerElement}
|
||||
</PieChart>
|
||||
@@ -760,7 +818,7 @@ const CallbackDataCard = ({mainTitle, secondTitle, mainElement, secondaryElement
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
const TableDataCard = ({data, title, leftColumnTitle, rightColumnTitle, leftKey, rightKey, width="100%"}) => {
|
||||
const TableDataCard = ({data, title, leftColumnTitle, rightColumnTitle, leftKey, rightKey, width="100%", onRowClick}) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<Paper elevation={5} style={{
|
||||
@@ -786,7 +844,7 @@ const TableDataCard = ({data, title, leftColumnTitle, rightColumnTitle, leftKey,
|
||||
</TableHead>
|
||||
<TableBody >
|
||||
{data.map( (d, index) => (
|
||||
<TableRow hover key={d[leftKey] + index}>
|
||||
<TableRow hover key={d[leftKey] + index} onClick={() => {onRowClick(d[leftKey])}} style={{cursor: "pointer"}}>
|
||||
<MythicTableCell>{d[leftKey]}</MythicTableCell>
|
||||
<MythicTableCell>{d[rightKey]}</MythicTableCell>
|
||||
</TableRow>
|
||||
|
||||
@@ -15,7 +15,7 @@ import jwt_decode from 'jwt-decode';
|
||||
import {meState} from './cache';
|
||||
|
||||
export const mythicVersion = "3.2.11";
|
||||
export const mythicUIVersion = "0.1.49";
|
||||
export const mythicUIVersion = "0.1.50";
|
||||
|
||||
let fetchingNewToken = false;
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/new/static/css/main.00d51b79.css",
|
||||
"main.js": "/new/static/js/main.7cf1a3b9.js",
|
||||
"main.js": "/new/static/js/main.5d55aca5.js",
|
||||
"static/media/mythic@2x.png": "/new/static/media/mythic@2x.7c5b62b471ac779fd706.png",
|
||||
"static/media/mythic_red_small.svg": "/new/static/media/mythic_red_small.793b41cc7135cdede246661ec232976b.svg",
|
||||
"index.html": "/new/index.html",
|
||||
"main.00d51b79.css.map": "/new/static/css/main.00d51b79.css.map",
|
||||
"main.7cf1a3b9.js.map": "/new/static/js/main.7cf1a3b9.js.map"
|
||||
"main.5d55aca5.js.map": "/new/static/js/main.5d55aca5.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.00d51b79.css",
|
||||
"static/js/main.7cf1a3b9.js"
|
||||
"static/js/main.5d55aca5.js"
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/new/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><link rel="apple-touch-icon" href="/new/logo192.png"/><link rel="manifest" href="/new/manifest.json"/><title>Mythic</title><script defer="defer" src="/new/static/js/main.7cf1a3b9.js"></script><link href="/new/static/css/main.00d51b79.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/new/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><link rel="apple-touch-icon" href="/new/logo192.png"/><link rel="manifest" href="/new/manifest.json"/><title>Mythic</title><script defer="defer" src="/new/static/js/main.5d55aca5.js"></script><link href="/new/static/css/main.00d51b79.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
+3
-3
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user