Skip to content

Commit

Permalink
mythicRPC fixes and a few UI tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
its-a-feature committed Jan 24, 2025
1 parent 90ec9e2 commit 2772b6c
Show file tree
Hide file tree
Showing 33 changed files with 237 additions and 146 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ 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).

## [3.3.1-rc37] - 2025-01-24

### Changed

- Updated the comment added to files automatically tracked due to a secondary task fetching them
- Updating the onStart code to not delay and automatically fire for containers
- Updated the MythicRPCTaskSearch and MythicRPCFileSearch commands due to broken logic
- Added fields for the MythicRPCCallbackUpdate to indicate if the last_checkin time should be updated
- This requires also specifying which c2 profile the callback is using
- UpdateLastCheckinTime and UpdateLastCheckinTimeViaC2Profile
- Updated the CommandAugment container sync code to automatically add commands to existing callbacks, not just new ones
- Updated container sync messages to the "debug" level instead of "info" level
- Updated the task's creation completion handler to append new stdout output instead of overwriting

## [3.3.1-rc36] - 2025-01-18

### Changed
Expand Down
7 changes: 7 additions & 0 deletions MythicReactUI/CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -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.3.2] - 2025-01-24

### Changed

- Updated the default event log filter to be on 'info' instead of 'All Levels'
- Added a top banner if Mythic loses network connection to inform the operator

## [0.3.1] - 2025-01-18

### Changed
Expand Down
13 changes: 13 additions & 0 deletions MythicReactUI/src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,19 @@ export function App(props) {
{me?.user?.current_operation_banner_text}
</Typography>
}
{me.loggedIn && me?.badConnection
&&
<Typography style={{
backgroundColor: theme.palette.error.main,
width: "100%",
textAlign: "center",
fontWeight: "600",
color: "white",
border: `1px solid ${theme.topAppBarColor || "grey"}`
}}>
{"Can't connect to Mythic. Please check connection and refresh"}
</Typography>
}
<div style={{
margin: '0px 0px 0px 0px',
flexGrow: 1,
Expand Down
3 changes: 1 addition & 2 deletions MythicReactUI/src/components/EventFeedNotifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function EventFeedNotifications(props) {
fetchPolicy: "no-cache",
shouldResubscribe: true,
onError: (errorData) => {
snackActions.warning("Failed to get event notifications");
console.log(errorData);
}
});

Expand Down Expand Up @@ -63,7 +63,6 @@ export function EventFeedNotifications(props) {
}
}else if(error){
console.error(error);
snackActions.error("Mythic encountered an error getting operational event stream", {autoHideDuration: 2000});
}
}, [loading, data, error, me.user?.id]);
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Badge from '@mui/material/Badge';
import NotificationsActiveTwoToneIcon from '@mui/icons-material/NotificationsActiveTwoTone';
import { Link } from 'react-router-dom';
import { IconButton } from '@mui/material';
import {snackActions} from './utilities/Snackbar';
import {MythicStyledTooltip} from "./MythicComponents/MythicStyledTooltip";
import { useTheme } from '@mui/material/styles';

Expand All @@ -20,7 +19,6 @@ subscription OperationAlertCounts{
export function TopAppBarEventLogNotifications(props) {
const { loading, error, data } = useSubscription(SUB_Event_Logs, {
onError: data => {
snackActions.error("Mythic encountered an error getting event log messages: " + data.toString());
console.error(data);
}
});
Expand All @@ -35,7 +33,7 @@ export function TopAppBarEventLogNotifications(props) {
to='/new/EventFeed'
style={{float: "right"}}>
{error ? (
<Badge color="secondary" badgeContent={0}>
<Badge color="secondary" badgeContent={"X"}>
<NotificationsActiveTwoToneIcon fontSize={"large"} />
</Badge>
) : (
Expand All @@ -55,14 +53,13 @@ export function TopAppBarVerticalEventLogNotifications(props) {
const theme = useTheme();
const { loading, error, data } = useSubscription(SUB_Event_Logs, {
onError: data => {
snackActions.error("Mythic encountered an error getting event log messages: " + data.toString());
console.error(data);
}
});

return (
error ? (
<Badge color="secondary" badgeContent={0}>
<Badge color="secondary" badgeContent={"X"}>
<NotificationsActiveTwoToneIcon style={{color: theme.navBarTextIconColor}} fontSize={"medium"} />
</Badge>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export function TopAppBarEventingNotifications(props) {
setTotalRunning(newRunningCounts);
},
onError: data => {
snackActions.error("Mythic encountered an error getting eventing counts: " + data.toString());
console.error(data);
}
});
Expand All @@ -50,7 +49,7 @@ export function TopAppBarEventingNotifications(props) {
disableRipple={true}
to='/new/Eventing'>
{error ? (
<Badge color="secondary" badgeContent={0}>
<Badge color="secondary" badgeContent={"X"}>
<PlayCircleFilledTwoToneIcon fontSize={"large"} />
</Badge>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export const ResponseDisplayPlaintext = (props) =>{
height={props.expand ? "100%": undefined}
maxLines={props.expand ? undefined : 20}
width={"100%"}
//style={{backgroundColor: "transparent"}}
//autoScrollEditorIntoView={true}
wrapEnabled={wrapText}
minLines={1}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,6 @@ export const TaskLabelFlat = ({task, me, showOnSelectTask, onSelectTask, graphVi
}

}

const onClickEntry = (e) => {
if(showOnSelectTask){
onSelectTask(e);
Expand Down
2 changes: 1 addition & 1 deletion MythicReactUI/src/components/pages/EventFeed/EventFeed.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export function EventFeed(props){
const [operationeventlog, setOperationEventLog] = React.useState([]);
const [fromNow, setFromNow] = React.useState((new Date()).toISOString());
const [search, setSearch] = React.useState("");
const [level, setLevel] = React.useState("All Levels");
const [level, setLevel] = React.useState("info");
useSubscription(SUB_Event_Feed, {
variables: {fromNow}, fetchPolicy: "no-cache",
onData: ({data}) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const EventList = ({onUpdateLevel, onUpdateResolution, operationeventlog}) => {
export function EventFeedTable(props){
const theme = useTheme();
const [search, setSearch] = React.useState("");
const [level, setLevel] = React.useState("All Levels");
const [level, setLevel] = React.useState("info");
const levelOptions = [
"All Levels", "warning (unresolved)", "warning (resolved)", "info", "debug", "api"
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,23 @@ export function SettingsOperatorUIConfigDialog(props) {
light: initialPalette?.navBarColor?.light || operatorSettingDefaults.palette.navBarColor.light,
}
});
const paletteOptions = [
const paletteOptionsSolidColor = [
{name: "primary", display: "Primary"},
{name: "error", display: "Error"},
{name: "warning", display: "Warning"},
{name: "info", display: "Informational"},
{name: "success", display: "Success"},
{name: "secondary", display: "Secondary"},
{name: "background", display: "Background"},
{name: "text", display: "Text Color"},
{name: "pageHeader", display: "Page Headers"}
];
const paletteOptionsTextColor = [
{name: "tableHeader", display: "Table Headers"},
{name: "tableHover", display: "Table Hover"},
{name: "pageHeader", display: "Page Headers"},
{name: "paper", display: "Menu and Modals Background"},
{name: "selectedCallbackColor", display: "Currently active callback row highlight"},
{name: "selectedCallbackHierarchyColor", display: "Current Host highlight in tree views"}
];
{name: "selectedCallbackHierarchyColor", display: "Current Host highlight in tree views"},
{name: "paper", display: "Menu and Modals Background"},
{name: "background", display: "Background"}
]
const [resumeNotifications, setResumeNotifications] = React.useState(false);
const [_, updateSettings, clearSettings] = useSetMythicSetting();
const onChangeFontSize = (name, value, error) => {
Expand Down Expand Up @@ -583,7 +584,7 @@ export function SettingsOperatorUIConfigDialog(props) {

</MythicStyledTableCell>
</TableRow>
{paletteOptions.map(p => (
{paletteOptionsSolidColor.map(p => (
<TableRow hover key={p.display}>
<MythicStyledTableCell>{p.display}</MythicStyledTableCell>
<MythicStyledTableCell>
Expand All @@ -606,6 +607,50 @@ export function SettingsOperatorUIConfigDialog(props) {
</MythicStyledTableCell>
</TableRow>
))}
{paletteOptionsTextColor.map(p => (
<TableRow hover key={p.display}>
<MythicStyledTableCell>{p.display}</MythicStyledTableCell>
<MythicStyledTableCell>
<div style={{display: "flex", width: "100%", paddingRight: "15px"}}>
<div style={{display: "inline-block", width: "100%"}}>
<HexColorPicker style={{width: "100%"}} color={palette?.[p.name]?.dark} onChange={(v) => onChangePaletteColor(p.name, "dark", v)}/>
<HexColorInput color={palette?.[p.name]?.dark} onChange={(v) => onChangePaletteColor(p.name, "dark", v)}/>
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.[p.name]?.dark}}>
<Typography style={{color: palette.text.dark}}>Dark Mode Color</Typography>
</Box>
</div>
<div style={{display: "inline-block", width: "100%"}}>
<HexColorPicker style={{width: "100%"}} color={palette?.[p.name]?.light} onChange={(v) => onChangePaletteColor(p.name, "light", v)}/>
<HexColorInput color={palette?.[p.name]?.light} onChange={(v) => onChangePaletteColor(p.name, "light", v)}/>
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.[p.name]?.light}}>
<Typography style={{color: palette.text.light}}>Light Mode Color</Typography>
</Box>
</div>
</div>
</MythicStyledTableCell>
</TableRow>
))}
<TableRow hover>
<MythicStyledTableCell>Text Color</MythicStyledTableCell>
<MythicStyledTableCell>
<div style={{display: "flex", width: "100%", paddingRight: "15px"}}>
<div style={{display: "inline-block", width: "100%"}}>
<HexColorPicker style={{width: "100%"}} color={palette?.text?.dark} onChange={(v) => onChangePaletteColor("text", "dark", v)}/>
<HexColorInput color={palette?.text?.dark} onChange={(v) => onChangePaletteColor("text", "dark", v)}/>
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.background?.dark, display: "flex", alignItems: "center"}}>
<Typography style={{color: palette.text.dark, display: "inline-block"}}>Dark Mode Color</Typography>
</Box>
</div>
<div style={{display: "inline-block", width: "100%"}}>
<HexColorPicker style={{width: "100%"}} color={palette?.text?.light} onChange={(v) => onChangePaletteColor("text", "light", v)}/>
<HexColorInput color={palette?.text?.light} onChange={(v) => onChangePaletteColor("text", "light", v)}/>
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.background?.light, display: "flex", alignItems: "center"}}>
<Typography style={{color: palette.text.light, display: "inline-block"}}>Light Mode Color</Typography>
</Box>
</div>
</div>
</MythicStyledTableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
Expand Down
27 changes: 18 additions & 9 deletions MythicReactUI/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import jwt_decode from 'jwt-decode';
import {meState} from './cache';
import {getSkewedNow} from "./components/utilities/Time";

export const mythicUIVersion = "0.3.1";
export const mythicUIVersion = "0.3.2";

let fetchingNewToken = false;

Expand All @@ -36,9 +36,8 @@ let cache = new InMemoryCache({

let retryLink = new RetryLink({
delay: {
initial: 20,
max: 300,
jitter: true
initial: 2,
max: 10
},
attempts: {
max: 2,
Expand Down Expand Up @@ -121,7 +120,7 @@ const authLink = setContext( async (_, {headers}) => {
//console.log(decoded_token);
// JWT lifetime is 4 hours. If there's 2hrs or less left of the JWT, update it
let diff = (decoded_token.exp * 1000) - getSkewedNow();
let twoHours = 7200000; // 2 hours in miliseconds, this is half the JWT lifetime
let twoHours = 30 * 60000; // 30min in milliseconds
// we want to make sure we try to get a new access_token while the current one is still active or it'll fail
if(!isJWTValid()){
console.log("token is no longer valid, try to get a new token");
Expand Down Expand Up @@ -210,9 +209,9 @@ const errorLink = onError(({ graphQLErrors, networkError }) => {
console.log(networkError.extensions, networkError.message);

if(networkError.extensions === undefined){
snackActions.error("Failed to connect to Mythic, please refresh");
FailedRefresh();
window.location = "/new/login";
meState({...meState(), badConnection: true});
//FailedRefresh();
//window.location = "/new/login";
return;
}
switch (networkError.extensions.code) {
Expand Down Expand Up @@ -295,7 +294,17 @@ const websocketAddress = () =>{
}
const wsClient = createClient({
url: websocketAddress(),
reconnectionAttempts: 10,
reconnectionAttempts: 3,
on: {
error: (err) => {
console.log("in on.error", err);
meState({...meState(), badConnection: true});
},
connected: (socket) => {
console.log("in on.connected", socket);
meState({...meState(), badConnection: false});
}
},
connectionParams: () => {
return {
Authorization: `Bearer ${localStorage.getItem('access_token')}`,
Expand Down
12 changes: 9 additions & 3 deletions MythicReactUI/src/themes/GlobalStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ tspan {
linear-gradient(90deg, ${(props) => props.theme.palette.secondary.main} 50%, transparent 0) repeat-x,
linear-gradient(90deg, ${(props) => props.theme.palette.secondary.main} 50%, transparent 0) repeat-x,
linear-gradient(0deg, ${(props) => props.theme.palette.secondary.main} 50%, transparent 0) repeat-y,
linear-gradient(0deg, ${(props) => props.theme.palette.secondary.main} 50%, transparent 0) repeat-y;
background-size: 8px 3px, 8px 3px, 3px 8px, 3px 8px;
background-position: 0 0, 0 100%, 0 0, 100% 0; // top bottom left right
linear-gradient(0deg, ${(props) => props.theme.palette.secondary.main} 50%, transparent 0) repeat-y !important;
background-size: 8px 3px, 8px 3px, 3px 8px, 3px 8px !important;
background-position: 0 0, 0 100%, 0 0, 100% 0 !important; // top bottom left right
}
*::-webkit-scrollbar {
Expand Down Expand Up @@ -337,4 +337,10 @@ tspan {
.MuiTabs-scrollButtons.Mui-disabled {
opacity: 0.3;
}
.ace_editor{
//background: transparent;
}
.ace_gutter {
//background: transparent !important;
}
`
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.1-rc35
3.3.1-rc37
2 changes: 1 addition & 1 deletion mythic-docker/src/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.1-rc36
3.3.1-rc37
11 changes: 7 additions & 4 deletions mythic-docker/src/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import (
"github.com/its-a-feature/Mythic/rabbitmq"
"github.com/its-a-feature/Mythic/utils"
"github.com/its-a-feature/Mythic/webserver"
"net/http"
)

//import _ "net/http/pprof"
import _ "net/http/pprof"

func main() {
//go func() {
// fmt.Println(http.ListenAndServe("localhost:6060", nil))
//}()
// for profiling go code, use parca
go func() {
fmt.Println(http.ListenAndServe("localhost:6060", nil))
// docker run --name parca --rm -p 7070:7070 -v "${PWD}/parca.yaml:/parca.yaml" --net host ghcr.io/parca-dev/parca:v0.22.0 /parca --config-path="/parca.yaml"
}()
// initialize configuration based on .env and environment variables
fmt.Print("Step 1/6 - Initializing utilities\n")
utils.Initialize()
Expand Down
Loading

0 comments on commit 2772b6c

Please sign in to comment.