forked from p15670423/monkey
Merge pull request #1688 from guardicore/1640-simplify-log-download
1640 simplify log download
This commit is contained in:
commit
81bc579aa5
|
@ -8,11 +8,13 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
## [Unreleased]
|
||||
### Added
|
||||
- credentials.json file for storing Monkey Island user login information. #1206
|
||||
- The ability to download the Monkey Island logs from the Infection Map page. #1640
|
||||
|
||||
### Changed
|
||||
- "Communicate as Backdoor User" PBA's HTTP requests to request headers only and
|
||||
include a timeout. #1577
|
||||
- The setup procedure for custom server_config.json files to be simpler. #1576
|
||||
- "Logs" page renamed to "Telemetries". #1640
|
||||
|
||||
### Removed
|
||||
- The VSFTPD exploiter. #1533
|
||||
|
@ -32,6 +34,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Hostname system info collector. #1535
|
||||
- Max iterations and timeout between iterations config options. #1600
|
||||
- MITRE ATT&CK configuration screen. #1532
|
||||
- Island log download button from "Telemetries"(previously called "Logs") page. #1640
|
||||
|
||||
### Fixed
|
||||
- A bug in network map page that caused delay of telemetry log loading. #1545
|
||||
|
|
|
@ -156,13 +156,23 @@ The Monkey performs queries out to the Internet on two separate occasions:
|
|||
|
||||
## Logging and how to find logs
|
||||
|
||||
### Monkey Island server logs
|
||||
### Downloading logs
|
||||
|
||||
You can download the Monkey Island's log file directly from the UI. Click the "log" section and choose **Download Monkey Island internal logfile**, like so:
|
||||
Both Monkey Agent and Monkey Island logs can be found in the Infection Map page. Click on the
|
||||
machine from which you want to download logs and press the "Download log" button on the side panel.
|
||||
Note that you can only download the Monkey Island log by clicking on the Monkey Island machine in
|
||||
the Infection Map.
|
||||
|
||||
![How to download Monkey Island internal log file](/images/faq/download_log_monkey_island.png "How to download Monkey Island internal log file")
|
||||
![How to download logs](/images/faq/log_download.jpg "How to download logs")
|
||||
|
||||
It can also be found as a local file on the Monkey Island server system in the specified
|
||||
### Log locations
|
||||
|
||||
If the logs can't be downloaded through the UI for any reason, you can collect the log files
|
||||
directly from the machine where an Agent or Monkey Island ran.
|
||||
|
||||
#### Monkey Island server log
|
||||
|
||||
The Monkey Island's log file is located in the
|
||||
[data directory]({{< ref "/reference/data_directory" >}}).
|
||||
|
||||
The log enables you to see which requests were requested from the server and extra logs from the backend logic. The log will contain entries like these:
|
||||
|
@ -177,7 +187,7 @@ It's also possible to change the default log level by editing `log_level` value
|
|||
`log_level` can be set to `info`(default, less verbose) or `debug`(more verbose).
|
||||
|
||||
|
||||
### Infection Monkey agent logs
|
||||
#### Infection Monkey agent logs
|
||||
|
||||
The Infection Monkey agent log file can be found in the following paths on machines where it was executed:
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 62 KiB |
Binary file not shown.
After Width: | Height: | Size: 209 KiB |
|
@ -91,7 +91,7 @@ const SideNavComponent = ({disabled,
|
|||
</NavLink></li>
|
||||
<li><NavLink to='/infection/telemetry'
|
||||
className={getNavLinkClass()}>
|
||||
Logs
|
||||
Telemetries
|
||||
</NavLink></li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -4,8 +4,11 @@ import {faHandPointLeft} from '@fortawesome/free-solid-svg-icons/faHandPointLeft
|
|||
import {faQuestionCircle} from '@fortawesome/free-solid-svg-icons/faQuestionCircle'
|
||||
import Toggle from 'react-toggle';
|
||||
import {OverlayTrigger, Tooltip} from 'react-bootstrap';
|
||||
import download from 'downloadjs'
|
||||
import AuthComponent from '../../AuthComponent';
|
||||
import {
|
||||
AgentLogDownloadButton,
|
||||
IslandLogDownloadButton
|
||||
} from '../../ui-components/LogDownloadButtons';
|
||||
|
||||
class PreviewPaneComponent extends AuthComponent {
|
||||
|
||||
|
@ -13,7 +16,7 @@ class PreviewPaneComponent extends AuthComponent {
|
|||
return (
|
||||
<OverlayTrigger placement="top"
|
||||
overlay={<Tooltip id="tooltip">{text}</Tooltip>}
|
||||
delay={{ show: 250, hide: 400 }}>
|
||||
delay={{show: 250, hide: 400}}>
|
||||
<a><FontAwesomeIcon icon={faQuestionCircle} style={{'marginRight': '0.5em'}}/></a>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
|
@ -94,43 +97,29 @@ class PreviewPaneComponent extends AuthComponent {
|
|||
);
|
||||
}
|
||||
|
||||
unescapeLog(st) {
|
||||
return st.substr(1, st.length - 2) // remove quotation marks on beginning and end of string.
|
||||
.replace(/\\n/g, '\n')
|
||||
.replace(/\\r/g, '\r')
|
||||
.replace(/\\t/g, '\t')
|
||||
.replace(/\\b/g, '\b')
|
||||
.replace(/\\f/g, '\f')
|
||||
.replace(/\\"/g, '"')
|
||||
.replace(/\\'/g, '\'')
|
||||
.replace(/\\&/g, '&');
|
||||
}
|
||||
|
||||
downloadLog(asset) {
|
||||
this.authFetch('/api/log?id=' + asset.id)
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
let timestamp = res['timestamp'];
|
||||
timestamp = timestamp.substr(0, timestamp.indexOf('.'));
|
||||
let filename = res['monkey_label'].split(':').join('-') + ' - ' + timestamp + '.log';
|
||||
let logContent = this.unescapeLog(res['log']);
|
||||
download(logContent, filename, 'text/plain');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
downloadLogRow(asset) {
|
||||
downloadLogsRow(asset) {
|
||||
return (
|
||||
<>
|
||||
<tr>
|
||||
<th>
|
||||
Download Log
|
||||
Download Monkey Agent Log
|
||||
</th>
|
||||
<td>
|
||||
<a type='button'
|
||||
className={asset.has_log ? 'btn btn-primary' : 'btn btn-primary disabled'}
|
||||
onClick={() => this.downloadLog(asset)}>Download</a>
|
||||
<AgentLogDownloadButton url={'/api/log?id=' + asset.id}
|
||||
variant={asset.has_log ? undefined : 'disabled'}/>
|
||||
</td>
|
||||
</tr>
|
||||
{(asset['group'].includes('island')) &&
|
||||
<tr>
|
||||
<th>
|
||||
Download Island Server Log
|
||||
</th>
|
||||
<td>
|
||||
<IslandLogDownloadButton url={'/api/log/island/download'} />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -194,7 +183,7 @@ class PreviewPaneComponent extends AuthComponent {
|
|||
{this.servicesRow(asset)}
|
||||
{this.accessibleRow(asset)}
|
||||
{this.forceKillRow(asset)}
|
||||
{this.downloadLogRow(asset)}
|
||||
{this.downloadLogsRow(asset)}
|
||||
</tbody>
|
||||
</table>
|
||||
{this.exploitsTimeline(asset)}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import React from 'react';
|
||||
import {Button, Col} from 'react-bootstrap';
|
||||
import {Col} from 'react-bootstrap';
|
||||
import AuthService from '../../services/AuthService';
|
||||
import download from 'downloadjs';
|
||||
import TelemetryLogTable from '../ui-components/TelemetryLogTable'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||
|
||||
import '../../styles/pages/TelemetryPage.scss';
|
||||
import {faDownload} from '@fortawesome/free-solid-svg-icons/faDownload';
|
||||
|
||||
|
||||
class TelemetryPageComponent extends React.Component {
|
||||
|
@ -19,35 +16,15 @@ class TelemetryPageComponent extends React.Component {
|
|||
};
|
||||
}
|
||||
|
||||
downloadIslandLog = () => {
|
||||
this.authFetch('/api/log/island/download')
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
let filename = 'Island_log';
|
||||
let logContent = (res['log_file']);
|
||||
download(logContent, filename, 'text/plain');
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Col sm={{offset: 3, span: 9}} md={{offset: 3, span: 9}}
|
||||
lg={{offset: 3, span: 9}} xl={{offset: 2, span: 7}}
|
||||
className={'main'}>
|
||||
<div>
|
||||
<h1 className="page-title">Logs</h1>
|
||||
<h1 className="page-title">Agent telemetries</h1>
|
||||
<TelemetryLogTable/>
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="page-title"> Monkey Island Logs </h1>
|
||||
<div className="text-center" style={{marginBottom: '20px'}}>
|
||||
<p style={{'marginBottom': '2em', 'fontSize': '1.2em'}}> Download Monkey Island internal log file </p>
|
||||
<Button bsSize="large" onClick={() => {
|
||||
this.downloadIslandLog();
|
||||
}}>
|
||||
<FontAwesomeIcon icon={faDownload}/> Download </Button>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import React from 'react';
|
||||
import AuthComponent from '../AuthComponent';
|
||||
import download from 'downloadjs';
|
||||
import {Button} from 'react-bootstrap';
|
||||
|
||||
const authComponent = new AuthComponent({})
|
||||
|
||||
type Props = { url: string, filename: string, variant?: string}
|
||||
|
||||
|
||||
|
||||
export const AgentLogDownloadButton = ({ url, variant = 'primary'}: Props) => {
|
||||
|
||||
function unescapeLog(st) {
|
||||
return st.substr(1, st.length - 2) // remove quotation marks on beginning and end of string.
|
||||
.replace(/\\n/g, '\n')
|
||||
.replace(/\\r/g, '\r')
|
||||
.replace(/\\t/g, '\t')
|
||||
.replace(/\\b/g, '\b')
|
||||
.replace(/\\f/g, '\f')
|
||||
.replace(/\\"/g, '"')
|
||||
.replace(/\\'/g, '\'')
|
||||
.replace(/\\&/g, '&');
|
||||
}
|
||||
|
||||
function downloadAgentLog() {
|
||||
authComponent.authFetch(url)
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
let timestamp = res['timestamp'];
|
||||
timestamp = timestamp.substr(0, timestamp.indexOf('.'));
|
||||
let filename = res['monkey_label'].split(':').join('-') + ' - ' + timestamp + '.log';
|
||||
let logContent = unescapeLog(res['log']);
|
||||
download(logContent, filename, 'text/plain');
|
||||
});
|
||||
}
|
||||
|
||||
return (<Button variant={variant}
|
||||
onClick={downloadAgentLog}>
|
||||
Download Log
|
||||
</Button>);
|
||||
}
|
||||
|
||||
|
||||
export const IslandLogDownloadButton = ({ url, variant = 'primary'}: Props) => {
|
||||
function downloadIslandLog() {
|
||||
authComponent.authFetch(url)
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
let filename = 'Island_log';
|
||||
let logContent = (res['log_file']);
|
||||
download(logContent, filename, 'text/plain');
|
||||
});
|
||||
}
|
||||
return (<Button variant={variant}
|
||||
onClick={downloadIslandLog}>
|
||||
Download Log
|
||||
</Button>);
|
||||
}
|
Loading…
Reference in New Issue